1 // Copyright 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.
8 #include "base/message_loop/message_loop.h"
9 #include "base/prefs/scoped_user_pref_update.h"
10 #include "base/strings/stringprintf.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/threading/sequenced_worker_pool.h"
13 #include "chrome/browser/managed_mode/managed_user_sync_service.h"
14 #include "chrome/browser/managed_mode/managed_user_sync_service_factory.h"
15 #include "chrome/common/pref_names.h"
16 #include "chrome/test/base/testing_profile.h"
17 #include "sync/api/attachments/attachment_id.h"
18 #include "sync/api/attachments/attachment_service_proxy_for_test.h"
19 #include "sync/api/sync_change.h"
20 #include "sync/api/sync_error_factory_mock.h"
21 #include "sync/protocol/sync.pb.h"
22 #include "testing/gtest/include/gtest/gtest.h"
24 #if defined(OS_CHROMEOS)
25 #include "chrome/browser/chromeos/login/default_user_images.h"
28 using sync_pb::ManagedUserSpecifics
;
29 using syncer::MANAGED_USERS
;
30 using syncer::SyncChange
;
31 using syncer::SyncChangeList
;
32 using syncer::SyncChangeProcessor
;
33 using syncer::SyncData
;
34 using syncer::SyncDataList
;
35 using syncer::SyncError
;
36 using syncer::SyncErrorFactory
;
37 using syncer::SyncMergeResult
;
41 class MockChangeProcessor
: public SyncChangeProcessor
{
43 MockChangeProcessor() {}
44 virtual ~MockChangeProcessor() {}
46 // SyncChangeProcessor implementation:
47 virtual SyncError
ProcessSyncChanges(
48 const tracked_objects::Location
& from_here
,
49 const SyncChangeList
& change_list
) OVERRIDE
;
51 virtual SyncDataList
GetAllSyncData(syncer::ModelType type
) const
53 return SyncDataList();
56 const SyncChangeList
& changes() const { return change_list_
; }
57 SyncChange
GetChange(const std::string
& id
) const;
60 SyncChangeList change_list_
;
63 SyncError
MockChangeProcessor::ProcessSyncChanges(
64 const tracked_objects::Location
& from_here
,
65 const SyncChangeList
& change_list
) {
66 change_list_
= change_list
;
70 SyncChange
MockChangeProcessor::GetChange(const std::string
& id
) const {
71 for (SyncChangeList::const_iterator it
= change_list_
.begin();
72 it
!= change_list_
.end(); ++it
) {
73 if (it
->sync_data().GetSpecifics().managed_user().id() == id
)
79 // Callback for ManagedUserSyncService::GetManagedUsersAsync().
80 void GetManagedUsersCallback(const base::DictionaryValue
** dict
,
81 const base::DictionaryValue
* managed_users
) {
82 *dict
= managed_users
;
87 class ManagedUserSyncServiceTest
: public ::testing::Test
{
89 ManagedUserSyncServiceTest();
90 virtual ~ManagedUserSyncServiceTest();
93 scoped_ptr
<SyncChangeProcessor
> CreateChangeProcessor();
94 scoped_ptr
<SyncErrorFactory
> CreateErrorFactory();
95 SyncData
CreateRemoteData(const std::string
& id
,
96 const std::string
& name
,
97 const std::string
& avatar
);
99 PrefService
* prefs() { return profile_
.GetPrefs(); }
100 ManagedUserSyncService
* service() { return service_
; }
101 MockChangeProcessor
* change_processor() { return change_processor_
; }
104 base::MessageLoop message_loop
;
105 TestingProfile profile_
;
106 ManagedUserSyncService
* service_
;
108 // Owned by the ManagedUserSyncService.
109 MockChangeProcessor
* change_processor_
;
111 // A unique ID for creating "remote" Sync data.
115 ManagedUserSyncServiceTest::ManagedUserSyncServiceTest()
116 : change_processor_(NULL
),
118 service_
= ManagedUserSyncServiceFactory::GetForProfile(&profile_
);
121 ManagedUserSyncServiceTest::~ManagedUserSyncServiceTest() {}
123 scoped_ptr
<SyncChangeProcessor
>
124 ManagedUserSyncServiceTest::CreateChangeProcessor() {
125 EXPECT_FALSE(change_processor_
);
126 change_processor_
= new MockChangeProcessor();
127 return scoped_ptr
<SyncChangeProcessor
>(change_processor_
);
130 scoped_ptr
<SyncErrorFactory
>
131 ManagedUserSyncServiceTest::CreateErrorFactory() {
132 return scoped_ptr
<SyncErrorFactory
>(new syncer::SyncErrorFactoryMock());
135 SyncData
ManagedUserSyncServiceTest::CreateRemoteData(
136 const std::string
& id
,
137 const std::string
& name
,
138 const std::string
& chrome_avatar
) {
139 ::sync_pb::EntitySpecifics specifics
;
140 specifics
.mutable_managed_user()->set_id(id
);
141 specifics
.mutable_managed_user()->set_name(name
);
142 specifics
.mutable_managed_user()->set_acknowledged(true);
143 if (!chrome_avatar
.empty())
144 specifics
.mutable_managed_user()->set_chrome_avatar(chrome_avatar
);
146 return SyncData::CreateRemoteData(
150 syncer::AttachmentIdList(),
151 syncer::AttachmentServiceProxyForTest::Create());
154 TEST_F(ManagedUserSyncServiceTest
, MergeEmpty
) {
155 SyncMergeResult result
=
156 service()->MergeDataAndStartSyncing(MANAGED_USERS
,
158 CreateChangeProcessor(),
159 CreateErrorFactory());
160 EXPECT_FALSE(result
.error().IsSet());
161 EXPECT_EQ(0, result
.num_items_added());
162 EXPECT_EQ(0, result
.num_items_modified());
163 EXPECT_EQ(0, result
.num_items_deleted());
164 EXPECT_EQ(0, result
.num_items_before_association());
165 EXPECT_EQ(0, result
.num_items_after_association());
166 EXPECT_EQ(0u, service()->GetManagedUsers()->size());
167 EXPECT_EQ(0u, change_processor()->changes().size());
169 service()->StopSyncing(MANAGED_USERS
);
170 service()->Shutdown();
173 TEST_F(ManagedUserSyncServiceTest
, MergeExisting
) {
174 const char kNameKey
[] = "name";
175 const char kAcknowledgedKey
[] = "acknowledged";
176 const char kChromeAvatarKey
[] = "chromeAvatar";
178 const char kUserId1
[] = "aaaaa";
179 const char kUserId2
[] = "bbbbb";
180 const char kUserId3
[] = "ccccc";
181 const char kUserId4
[] = "ddddd";
182 const char kName1
[] = "Anchor";
183 const char kName2
[] = "Buzz";
184 const char kName3
[] = "Crush";
185 const char kName4
[] = "Dory";
186 const char kAvatar1
[] = "";
187 #if defined(OS_CHROMEOS)
188 const char kAvatar2
[] = "chromeos-avatar-index:0";
189 const char kAvatar3
[] = "chromeos-avatar-index:20";
191 const char kAvatar2
[] = "chrome-avatar-index:0";
192 const char kAvatar3
[] = "chrome-avatar-index:20";
194 const char kAvatar4
[] = "";
196 DictionaryPrefUpdate
update(prefs(), prefs::kManagedUsers
);
197 base::DictionaryValue
* managed_users
= update
.Get();
198 base::DictionaryValue
* dict
= new base::DictionaryValue
;
199 dict
->SetString(kNameKey
, kName1
);
200 managed_users
->Set(kUserId1
, dict
);
201 dict
= new base::DictionaryValue
;
202 dict
->SetString(kNameKey
, kName2
);
203 dict
->SetBoolean(kAcknowledgedKey
, true);
204 managed_users
->Set(kUserId2
, dict
);
207 const base::DictionaryValue
* async_managed_users
= NULL
;
208 service()->GetManagedUsersAsync(
209 base::Bind(&GetManagedUsersCallback
, &async_managed_users
));
211 SyncDataList initial_sync_data
;
212 initial_sync_data
.push_back(CreateRemoteData(kUserId2
, kName2
, kAvatar2
));
213 initial_sync_data
.push_back(CreateRemoteData(kUserId3
, kName3
, kAvatar3
));
214 initial_sync_data
.push_back(CreateRemoteData(kUserId4
, kName4
, kAvatar4
));
216 SyncMergeResult result
=
217 service()->MergeDataAndStartSyncing(MANAGED_USERS
,
219 CreateChangeProcessor(),
220 CreateErrorFactory());
221 EXPECT_FALSE(result
.error().IsSet());
222 EXPECT_EQ(2, result
.num_items_added());
223 EXPECT_EQ(1, result
.num_items_modified());
224 EXPECT_EQ(0, result
.num_items_deleted());
225 EXPECT_EQ(2, result
.num_items_before_association());
226 EXPECT_EQ(4, result
.num_items_after_association());
228 const base::DictionaryValue
* managed_users
= service()->GetManagedUsers();
229 EXPECT_EQ(4u, managed_users
->size());
230 EXPECT_TRUE(async_managed_users
);
231 EXPECT_TRUE(managed_users
->Equals(async_managed_users
));
234 const base::DictionaryValue
* managed_user
= NULL
;
235 ASSERT_TRUE(managed_users
->GetDictionary(kUserId2
, &managed_user
));
236 ASSERT_TRUE(managed_user
);
238 EXPECT_TRUE(managed_user
->GetString(kNameKey
, &name
));
239 EXPECT_EQ(kName2
, name
);
240 bool acknowledged
= false;
241 EXPECT_TRUE(managed_user
->GetBoolean(kAcknowledgedKey
, &acknowledged
));
242 EXPECT_TRUE(acknowledged
);
244 EXPECT_TRUE(managed_user
->GetString(kChromeAvatarKey
, &avatar
));
245 EXPECT_EQ(kAvatar2
, avatar
);
248 const base::DictionaryValue
* managed_user
= NULL
;
249 ASSERT_TRUE(managed_users
->GetDictionary(kUserId3
, &managed_user
));
250 ASSERT_TRUE(managed_user
);
252 EXPECT_TRUE(managed_user
->GetString(kNameKey
, &name
));
253 EXPECT_EQ(kName3
, name
);
254 bool acknowledged
= false;
255 EXPECT_TRUE(managed_user
->GetBoolean(kAcknowledgedKey
, &acknowledged
));
256 EXPECT_TRUE(acknowledged
);
258 EXPECT_TRUE(managed_user
->GetString(kChromeAvatarKey
, &avatar
));
259 EXPECT_EQ(kAvatar3
, avatar
);
262 const base::DictionaryValue
* managed_user
= NULL
;
263 ASSERT_TRUE(managed_users
->GetDictionary(kUserId4
, &managed_user
));
264 ASSERT_TRUE(managed_user
);
266 EXPECT_TRUE(managed_user
->GetString(kNameKey
, &name
));
267 EXPECT_EQ(kName4
, name
);
268 bool acknowledged
= false;
269 EXPECT_TRUE(managed_user
->GetBoolean(kAcknowledgedKey
, &acknowledged
));
270 EXPECT_TRUE(acknowledged
);
272 EXPECT_TRUE(managed_user
->GetString(kChromeAvatarKey
, &avatar
));
273 EXPECT_EQ(kAvatar4
, avatar
);
276 EXPECT_EQ(1u, change_processor()->changes().size());
278 SyncChange change
= change_processor()->GetChange(kUserId1
);
279 ASSERT_TRUE(change
.IsValid());
280 EXPECT_EQ(SyncChange::ACTION_ADD
, change
.change_type());
281 const ManagedUserSpecifics
& managed_user
=
282 change
.sync_data().GetSpecifics().managed_user();
283 EXPECT_EQ(kName1
, managed_user
.name());
284 EXPECT_FALSE(managed_user
.acknowledged());
285 EXPECT_EQ(kAvatar1
, managed_user
.chrome_avatar());
289 TEST_F(ManagedUserSyncServiceTest
, GetAvatarIndex
) {
291 EXPECT_TRUE(ManagedUserSyncService::GetAvatarIndex(std::string(), &avatar
));
292 EXPECT_EQ(ManagedUserSyncService::kNoAvatar
, avatar
);
294 int avatar_index
= 4;
295 #if defined(OS_CHROMEOS)
296 avatar_index
+= chromeos::kFirstDefaultImageIndex
;
298 std::string avatar_str
=
299 ManagedUserSyncService::BuildAvatarString(avatar_index
);
300 #if defined(OS_CHROMEOS)
301 EXPECT_EQ(base::StringPrintf("chromeos-avatar-index:%d", avatar_index
),
304 EXPECT_EQ(base::StringPrintf("chrome-avatar-index:%d", avatar_index
),
307 EXPECT_TRUE(ManagedUserSyncService::GetAvatarIndex(avatar_str
, &avatar
));
308 EXPECT_EQ(avatar_index
, avatar
);
311 #if defined(OS_CHROMEOS)
312 avatar_index
+= chromeos::kFirstDefaultImageIndex
;
314 avatar_str
= ManagedUserSyncService::BuildAvatarString(avatar_index
);
315 #if defined(OS_CHROMEOS)
316 EXPECT_EQ(base::StringPrintf("chromeos-avatar-index:%d", avatar_index
),
319 EXPECT_EQ(base::StringPrintf("chrome-avatar-index:%d", avatar_index
),
322 EXPECT_TRUE(ManagedUserSyncService::GetAvatarIndex(avatar_str
, &avatar
));
323 EXPECT_EQ(avatar_index
, avatar
);
325 EXPECT_FALSE(ManagedUserSyncService::GetAvatarIndex("wrong-prefix:5",
327 #if defined(OS_CHROMEOS)
328 EXPECT_FALSE(ManagedUserSyncService::GetAvatarIndex("chromeos-avatar-indes:2",
332 ManagedUserSyncService::GetAvatarIndex("chromeos-avatar-indexxx:2",
335 EXPECT_FALSE(ManagedUserSyncService::GetAvatarIndex("chromeos-avatar-index:",
338 EXPECT_FALSE(ManagedUserSyncService::GetAvatarIndex("chromeos-avatar-index:x",
341 EXPECT_FALSE(ManagedUserSyncService::GetAvatarIndex("chrome-avatar-index:5",
344 EXPECT_FALSE(ManagedUserSyncService::GetAvatarIndex("chrome-avatar-indes:2",
347 EXPECT_FALSE(ManagedUserSyncService::GetAvatarIndex("chrome-avatar-indexxx:2",
350 EXPECT_FALSE(ManagedUserSyncService::GetAvatarIndex("chrome-avatar-index:",
353 EXPECT_FALSE(ManagedUserSyncService::GetAvatarIndex("chrome-avatar-index:x",
356 EXPECT_FALSE(ManagedUserSyncService::GetAvatarIndex("chromeos-avatar-index:5",