Upstream version 5.34.98.0
[platform/framework/web/crosswalk.git] / src / google_apis / gcm / engine / user_list_unittest.cc
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.
4
5 #include "google_apis/gcm/engine/user_list.h"
6
7 #include <string>
8 #include <vector>
9
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"
19
20 namespace gcm {
21
22 namespace {
23
24 class GCMClientDelegate : public GCMClient::Delegate {
25  public:
26   explicit GCMClientDelegate(const std::string& username);
27   virtual ~GCMClientDelegate();
28
29   const std::string& GetUsername() const { return username_; }
30
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)
42       OVERRIDE {}
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();
49   }
50   virtual void OnLoadingCompleted() OVERRIDE {}
51
52  private:
53   std::string username_;
54 };
55
56 }  // namespace
57
58 class UserListTest : public testing::Test {
59  public:
60   UserListTest();
61   virtual ~UserListTest();
62
63   virtual void SetUp() OVERRIDE;
64
65   static size_t GetListSize(const UserList* user_list);
66   void SetDelegateCallback(const std::string& username,
67                            int64 user_serial_number);
68
69   scoped_ptr<UserList> BuildUserList();
70
71   void PumpLoop();
72
73   void UpdateCallback(bool success);
74
75   void Initialize(UserList* user_list, scoped_ptr<GCMStore::LoadResult> result);
76
77   void ResetLoop();
78
79  protected:
80   int64 last_assigned_serial_number_;
81   std::string last_assigned_username_;
82   scoped_ptr<GCMStore> gcm_store_;
83
84  private:
85   base::ScopedTempDir temp_directory_;
86   base::MessageLoop message_loop_;
87   scoped_ptr<base::RunLoop> run_loop_;
88 };
89
90 UserListTest::UserListTest()
91     : last_assigned_serial_number_(gcm::kInvalidSerialNumber) {}
92
93 UserListTest::~UserListTest() {}
94
95 void UserListTest::SetUp() {
96   ASSERT_TRUE(temp_directory_.CreateUniqueTempDir());
97 }
98
99 // static
100 size_t UserListTest::GetListSize(const UserList* user_list) {
101   return user_list->delegates_.size();
102 }
103
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;
108   ResetLoop();
109 }
110
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()));
116 }
117
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);
122   ResetLoop();
123 }
124
125 void UserListTest::ResetLoop() {
126   if (run_loop_ && run_loop_->running())
127     run_loop_->Quit();
128 }
129
130 void UserListTest::PumpLoop() {
131   run_loop_.reset(new base::RunLoop);
132   run_loop_->Run();
133 }
134
135 void UserListTest::UpdateCallback(bool success) { ASSERT_TRUE(success); }
136
137 GCMClientDelegate::GCMClientDelegate(const std::string& username)
138     : username_(username) {}
139
140 GCMClientDelegate::~GCMClientDelegate() {}
141
142 // Make sure it is possible to add a delegate, and that it is assigned a serial
143 // number.
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()));
148   PumpLoop();
149
150   // First adding a delegate.
151   scoped_ptr<GCMClientDelegate> delegate(new GCMClientDelegate("test_user_1"));
152   user_list->SetDelegate(
153       delegate->GetUsername(),
154       delegate.get(),
155       base::Bind(&UserListTest::SetDelegateCallback, base::Unretained(this)));
156   PumpLoop();
157
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()));
166 }
167
168 // Get the delegate that was added to the list by both serial number and
169 // username.
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()));
174   PumpLoop();
175
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(),
180       delegate.get(),
181       base::Bind(&UserListTest::SetDelegateCallback, base::Unretained(this)));
182   PumpLoop();
183
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_));
188 }
189
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()));
197   PumpLoop();
198
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(),
203       delegate.get(),
204       base::Bind(&UserListTest::SetDelegateCallback, base::Unretained(this)));
205   PumpLoop();
206
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()));
211   PumpLoop();
212
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()));
220
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
223   // not created.
224   user_list->SetDelegate(
225       delegate->GetUsername(),
226       delegate.get(),
227       base::Bind(&UserListTest::SetDelegateCallback, base::Unretained(this)));
228   PumpLoop();
229
230   EXPECT_EQ(1u, GetListSize(user_list.get()));
231   serial_number =
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()));
238 }
239
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()));
245   PumpLoop();
246
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(),
251       delegate1.get(),
252       base::Bind(&UserListTest::SetDelegateCallback, base::Unretained(this)));
253   PumpLoop();
254
255   int64 serial_number1 = last_assigned_serial_number_;
256
257   scoped_ptr<GCMClientDelegate> delegate2(new GCMClientDelegate("test_user_2"));
258   user_list->SetDelegate(
259       delegate2->GetUsername(),
260       delegate2.get(),
261       base::Bind(&UserListTest::SetDelegateCallback, base::Unretained(this)));
262   PumpLoop();
263
264   int64 serial_number2 = last_assigned_serial_number_;
265
266   // Ensuring that serial numbers are different.
267   EXPECT_EQ(2u, GetListSize(user_list.get()));
268
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()));
273   PumpLoop();
274
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));
281
282   // Setting and checking a delegate on the second user.
283   user_list->SetDelegate(
284       delegate2->GetUsername(),
285       delegate2.get(),
286       base::Bind(&UserListTest::SetDelegateCallback, base::Unretained(this)));
287   PumpLoop();
288
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));
297 }
298
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());
303
304   // Add a delegate first.
305   scoped_ptr<GCMClientDelegate> delegate(new GCMClientDelegate("test_user_1"));
306   user_list->SetDelegate(
307       delegate->GetUsername(),
308       delegate.get(),
309       base::Bind(&UserListTest::SetDelegateCallback, base::Unretained(this)));
310
311   EXPECT_EQ(gcm::kInvalidSerialNumber, last_assigned_serial_number_);
312   EXPECT_EQ("", last_assigned_username_);
313
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.
319   PumpLoop();
320   PumpLoop();
321
322   EXPECT_EQ(last_assigned_serial_number_,
323             user_list->GetSerialNumberForUsername(delegate->GetUsername()));
324   EXPECT_EQ(delegate->GetUsername(), last_assigned_username_);
325 }
326
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()));
334   PumpLoop();
335
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(),
340       delegate.get(),
341       base::Bind(&UserListTest::SetDelegateCallback, base::Unretained(this)));
342   PumpLoop();
343
344   last_assigned_serial_number_ = gcm::kInvalidSerialNumber;
345   last_assigned_username_ = "";
346
347   // Resetting the user list to make sure it is not initialized.
348   user_list = BuildUserList().Pass();
349
350   // Add a delegate again, this time no callback is expected until the list is
351   // initialized.
352   user_list->SetDelegate(
353       delegate->GetUsername(),
354       delegate.get(),
355       base::Bind(&UserListTest::SetDelegateCallback, base::Unretained(this)));
356
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.
362   PumpLoop();
363   PumpLoop();
364
365   EXPECT_EQ(last_assigned_serial_number_,
366             user_list->GetSerialNumberForUsername(delegate->GetUsername()));
367   EXPECT_EQ(delegate->GetUsername(), last_assigned_username_);
368 }
369
370 }  // namespace gcm