Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(225)

Side by Side Diff: chrome/browser/ui/app_list/app_list_syncable_service_unittest.cc

Issue 2952463002: App list sync unit tests (Closed)
Patch Set: App list sync unit tests Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/app_list/app_list_syncable_service.h" 5 #include "chrome/browser/ui/app_list/app_list_syncable_service.h"
6 #include "base/files/scoped_temp_dir.h" 6 #include "base/files/scoped_temp_dir.h"
7 #include "chrome/browser/extensions/extension_service.h" 7 #include "chrome/browser/extensions/extension_service.h"
8 #include "chrome/browser/profiles/profile_manager.h" 8 #include "chrome/browser/profiles/profile_manager.h"
9 #include "chrome/browser/ui/app_list/app_list_test_util.h" 9 #include "chrome/browser/ui/app_list/app_list_test_util.h"
10 #include "chrome/test/base/testing_browser_process.h" 10 #include "chrome/test/base/testing_browser_process.h"
11 #include "chrome/test/base/testing_profile.h" 11 #include "chrome/test/base/testing_profile.h"
12 #include "components/crx_file/id_util.h" 12 #include "components/crx_file/id_util.h"
13 #include "components/sync/model/attachments/attachment_service_proxy_for_test.h"
14 #include "components/sync/model/fake_sync_change_processor.h"
15 #include "components/sync/model/sync_error_factory.h"
16 #include "components/sync/model/sync_error_factory_mock.h"
17 #include "components/sync/protocol/sync.pb.h"
13 #include "extensions/browser/extension_system.h" 18 #include "extensions/browser/extension_system.h"
14 #include "extensions/common/constants.h" 19 #include "extensions/common/constants.h"
15 #include "ui/app_list/app_list_item.h" 20 #include "ui/app_list/app_list_item.h"
16 #include "ui/app_list/app_list_model.h" 21 #include "ui/app_list/app_list_model.h"
17 22
18 namespace { 23 namespace {
19 24
20 scoped_refptr<extensions::Extension> MakeApp( 25 scoped_refptr<extensions::Extension> MakeApp(
21 const std::string& name, 26 const std::string& name,
22 const std::string& id, 27 const std::string& id,
(...skipping 16 matching lines...) Expand all
39 std::string next_app_id = app_id; 44 std::string next_app_id = app_id;
40 size_t index = next_app_id.length() - 1; 45 size_t index = next_app_id.length() - 1;
41 while (index > 0 && next_app_id[index] == 'p') 46 while (index > 0 && next_app_id[index] == 'p')
42 next_app_id[index--] = 'a'; 47 next_app_id[index--] = 'a';
43 DCHECK(next_app_id[index] != 'p'); 48 DCHECK(next_app_id[index] != 'p');
44 next_app_id[index]++; 49 next_app_id[index]++;
45 DCHECK(crx_file::id_util::IdIsValid(next_app_id)); 50 DCHECK(crx_file::id_util::IdIsValid(next_app_id));
46 return next_app_id; 51 return next_app_id;
47 } 52 }
48 53
54 static const std::string UNSET = "__unset__";
xiyuan 2017/06/21 15:59:20 Global variables should only be POD. See https://g
rcui 2017/06/23 02:03:49 Done, thanks. Looking a lot better now :)
55
56 static const std::string INVALID_ORDINALS_ID = "invalid_ordinals";
57 static const std::string EMPTY_ITEM_NAME_ID = "empty_item_name";
58 static const std::string EMPTY_ITEM_NAME_UNSET_ID = "empty_item_name_unset";
59 static const std::string EMPTY_PARENT_ID = "empty_parent_id";
60 static const std::string EMPTY_PARENT_UNSET_ID = "empty_parent_id_unset";
61 static const std::string EMPTY_ORDINALS_ID = "empty_ordinals";
62 static const std::string EMPTY_ORDINALS_UNSET_ID = "empty_ordinals_unset";
63 static const std::string DUPE_ITEM_ID = "dupe_item_id";
64
65 syncer::SyncData CreateAppRemoteData(const std::string& id,
66 const std::string& name,
67 const std::string& parent_id,
68 const std::string& item_ordinal,
69 const std::string& item_pin_ordinal) {
70 sync_pb::EntitySpecifics specifics;
71 sync_pb::AppListSpecifics* app_list = specifics.mutable_app_list();
72 if (id != UNSET)
73 app_list->set_item_id(id);
74 app_list->set_item_type(sync_pb::AppListSpecifics_AppListItemType_TYPE_APP);
75 if (name != UNSET)
76 app_list->set_item_name(name);
77 if (parent_id != UNSET)
78 app_list->set_parent_id(parent_id);
79 if (item_ordinal != UNSET)
80 app_list->set_item_ordinal(item_ordinal);
81 if (item_pin_ordinal != UNSET)
82 app_list->set_item_pin_ordinal(item_pin_ordinal);
83
84 return syncer::SyncData::CreateRemoteData(
85 std::hash<std::string>{}(id), specifics, base::Time(),
86 syncer::AttachmentIdList(),
87 syncer::AttachmentServiceProxyForTest::Create());
88 }
89
90 syncer::SyncDataList CreateBadAppRemoteData(const std::string& id) {
91 syncer::SyncDataList sync_list;
92 // Invalid item_ordinal and item_pin_ordinal.
93 sync_list.push_back(CreateAppRemoteData(
khmel 2017/06/22 00:10:11 In case id == UNSET we create data with different
rcui 2017/06/23 02:03:49 Good point. I'm using a different constant for th
94 id == UNSET ? INVALID_ORDINALS_ID : id, "item_name", "parent_id",
95 "$$invalid_ordinal$$", "$$invalid_ordinal$$"));
stevenjb 2017/06/21 23:27:17 This should probably also be a constant
rcui 2017/06/23 02:03:48 Since it's only used in this function, I think it'
stevenjb 2017/06/23 19:46:05 Acknowledged.
96 // Empty item name.
97 sync_list.push_back(CreateAppRemoteData(id == UNSET ? EMPTY_ITEM_NAME_ID : id,
98 "", "parent_id", "ordinal",
99 "pinordinal"));
100 sync_list.push_back(
101 CreateAppRemoteData(id == UNSET ? EMPTY_ITEM_NAME_UNSET_ID : id, UNSET,
102 "parent_id", "ordinal", "pinordinal"));
103 // Empty parent ID.
104 sync_list.push_back(CreateAppRemoteData(id == UNSET ? EMPTY_PARENT_ID : id,
105 "item_name", "", "ordinal",
106 "pinordinal"));
107 sync_list.push_back(
108 CreateAppRemoteData(id == UNSET ? EMPTY_PARENT_UNSET_ID : id, "item_name",
109 UNSET, "ordinal", "pinordinal"));
110 // Empty item_ordinal and item_pin_ordinal.
111 sync_list.push_back(CreateAppRemoteData(id == UNSET ? EMPTY_ORDINALS_ID : id,
112 "item_name", "parent_id", "", ""));
113 sync_list.push_back(
114 CreateAppRemoteData(id == UNSET ? EMPTY_ORDINALS_UNSET_ID : id,
115 "item_name", "parent_id", UNSET, UNSET));
116 // Duplicate item_id.
117 sync_list.push_back(CreateAppRemoteData(id == UNSET ? DUPE_ITEM_ID : id,
118 "item_name", "parent_id", "ordinal",
119 "pinordinal"));
120 sync_list.push_back(CreateAppRemoteData(id == UNSET ? DUPE_ITEM_ID : id,
121 "item_name_dupe", "parent_id",
122 "ordinal", "pinordinal"));
123 // Empty item_id.
124 sync_list.push_back(CreateAppRemoteData("", "item_name", "parent_id",
125 "ordinal", "pinordinal"));
126 sync_list.push_back(CreateAppRemoteData(UNSET, "item_name", "parent_id",
127 "ordinal", "pinordinal"));
128 // All fields empty.
129 sync_list.push_back(CreateAppRemoteData("", "", "", "", ""));
130 sync_list.push_back(CreateAppRemoteData(UNSET, UNSET, UNSET, UNSET, UNSET));
131
132 return sync_list;
133 }
134
49 } // namespace 135 } // namespace
50 136
51 class AppListSyncableServiceTest : public AppListTestBase { 137 class AppListSyncableServiceTest : public AppListTestBase {
52 public: 138 public:
53 AppListSyncableServiceTest() = default; 139 AppListSyncableServiceTest() = default;
54 ~AppListSyncableServiceTest() override = default; 140 ~AppListSyncableServiceTest() override = default;
55 141
56 void SetUp() override { 142 void SetUp() override {
57 AppListTestBase::SetUp(); 143 AppListTestBase::SetUp();
58 144
59 // Make sure we have a Profile Manager. 145 // Make sure we have a Profile Manager.
60 DCHECK(temp_dir_.CreateUniqueTempDir()); 146 DCHECK(temp_dir_.CreateUniqueTempDir());
61 TestingBrowserProcess::GetGlobal()->SetProfileManager( 147 TestingBrowserProcess::GetGlobal()->SetProfileManager(
62 new ProfileManagerWithoutInit(temp_dir_.GetPath())); 148 new ProfileManagerWithoutInit(temp_dir_.GetPath()));
63 149
64 extensions::ExtensionSystem* extension_system = 150 extensions::ExtensionSystem* extension_system =
65 extensions::ExtensionSystem::Get(profile_.get()); 151 extensions::ExtensionSystem::Get(profile_.get());
66 DCHECK(extension_system); 152 DCHECK(extension_system);
67 app_list_syncable_service_.reset( 153 app_list_syncable_service_.reset(
68 new app_list::AppListSyncableService(profile_.get(), extension_system)); 154 new app_list::AppListSyncableService(profile_.get(), extension_system));
69 } 155 }
70 156
71 void TearDown() override { app_list_syncable_service_.reset(); } 157 void TearDown() override { app_list_syncable_service_.reset(); }
72 158
73 app_list::AppListModel* model() { 159 app_list::AppListModel* model() {
74 return app_list_syncable_service_->GetModel(); 160 return app_list_syncable_service_->GetModel();
75 } 161 }
76 162
163 const app_list::AppListSyncableService::SyncItem* GetSyncItem(
164 std::string id) {
xiyuan 2017/06/21 15:59:20 std::string -> const std::string& And can this be
rcui 2017/06/23 02:03:48 Done.
165 return app_list_syncable_service_->GetSyncItem(id);
166 }
167
168 protected:
169 std::unique_ptr<app_list::AppListSyncableService> app_list_syncable_service_;
khmel 2017/06/22 00:10:11 nit: can we leave it private and add getter:? pr
rcui 2017/06/23 02:03:48 Done.
170
77 private: 171 private:
78 base::ScopedTempDir temp_dir_; 172 base::ScopedTempDir temp_dir_;
79 std::unique_ptr<app_list::AppListSyncableService> app_list_syncable_service_;
80 173
81 DISALLOW_COPY_AND_ASSIGN(AppListSyncableServiceTest); 174 DISALLOW_COPY_AND_ASSIGN(AppListSyncableServiceTest);
82 }; 175 };
83 176
84 TEST_F(AppListSyncableServiceTest, OEMFolderForConflictingPos) { 177 TEST_F(AppListSyncableServiceTest, OEMFolderForConflictingPos) {
85 // Create a "web store" app. 178 // Create a "web store" app.
86 const std::string web_store_app_id(extensions::kWebStoreAppId); 179 const std::string web_store_app_id(extensions::kWebStoreAppId);
87 scoped_refptr<extensions::Extension> store = 180 scoped_refptr<extensions::Extension> store =
88 MakeApp("webstore", web_store_app_id, 181 MakeApp("webstore", web_store_app_id,
89 extensions::Extension::WAS_INSTALLED_BY_DEFAULT); 182 extensions::Extension::WAS_INSTALLED_BY_DEFAULT);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 EXPECT_FALSE(model()->top_level_item_list()->FindItemIndex(oem_app_id, 217 EXPECT_FALSE(model()->top_level_item_list()->FindItemIndex(oem_app_id,
125 &oem_app_index)); 218 &oem_app_index));
126 // But OEM folder is. 219 // But OEM folder is.
127 EXPECT_TRUE(model()->top_level_item_list()->FindItemIndex( 220 EXPECT_TRUE(model()->top_level_item_list()->FindItemIndex(
128 app_list::AppListSyncableService::kOemFolderId, &oem_folder_index)); 221 app_list::AppListSyncableService::kOemFolderId, &oem_folder_index));
129 222
130 // Ensure right item sequence. 223 // Ensure right item sequence.
131 EXPECT_EQ(some_app_index, web_store_app_index + 1); 224 EXPECT_EQ(some_app_index, web_store_app_index + 1);
132 EXPECT_EQ(oem_folder_index, web_store_app_index + 2); 225 EXPECT_EQ(oem_folder_index, web_store_app_index + 2);
133 } 226 }
227
228 TEST_F(AppListSyncableServiceTest, InitialMerge) {
229 syncer::SyncDataList sync_list;
230 sync_list.push_back(CreateAppRemoteData(
231 "item_id1", "item_name1", "parent_id1", "ordinal", "pinordinal"));
khmel 2017/06/22 00:10:11 nit: as an valid item id we probably better use id
khmel 2017/06/22 00:10:12 nit: as a valid ordinal, can we use something from
rcui 2017/06/23 02:03:48 The ordinals we use now are valid. They also make
rcui 2017/06/23 02:03:48 Done. Id's are generated with crx_file::id_util::
232 sync_list.push_back(CreateAppRemoteData(
233 "item_id2", "item_name2", "parent_id2", "ordinal", "pinordinal"));
234
235 app_list_syncable_service_->MergeDataAndStartSyncing(
236 syncer::APP_LIST, sync_list,
237 std::unique_ptr<syncer::SyncChangeProcessor>(
238 new syncer::FakeSyncChangeProcessor),
239 std::unique_ptr<syncer::SyncErrorFactory>(
240 new syncer::SyncErrorFactoryMock));
xiyuan 2017/06/21 15:59:20 nit: use base::MakeUnique<T>() instead of std::uni
rcui 2017/06/23 02:03:49 Done.
241 content::RunAllBlockingPoolTasksUntilIdle();
242
243 EXPECT_TRUE(GetSyncItem("item_id1"));
244 EXPECT_EQ("item_name1", GetSyncItem("item_id1")->item_name);
245 EXPECT_EQ("parent_id1", GetSyncItem("item_id1")->parent_id);
246 EXPECT_EQ("ordinal", GetSyncItem("item_id1")->item_ordinal.ToDebugString());
247 EXPECT_EQ("pinordinal",
248 GetSyncItem("item_id1")->item_pin_ordinal.ToDebugString());
249
250 EXPECT_TRUE(GetSyncItem("item_id2"));
251 EXPECT_EQ("item_name2", GetSyncItem("item_id2")->item_name);
252 EXPECT_EQ("parent_id2", GetSyncItem("item_id2")->parent_id);
253 EXPECT_EQ("ordinal", GetSyncItem("item_id2")->item_ordinal.ToDebugString());
254 EXPECT_EQ("pinordinal",
255 GetSyncItem("item_id2")->item_pin_ordinal.ToDebugString());
256 }
257
258 TEST_F(AppListSyncableServiceTest, InitialMerge_BadData) {
259 syncer::SyncDataList sync_list = CreateBadAppRemoteData(UNSET);
260
261 app_list_syncable_service_->MergeDataAndStartSyncing(
262 syncer::APP_LIST, sync_list,
263 std::unique_ptr<syncer::SyncChangeProcessor>(
264 new syncer::FakeSyncChangeProcessor),
265 std::unique_ptr<syncer::SyncErrorFactory>(
266 new syncer::SyncErrorFactoryMock));
267 content::RunAllBlockingPoolTasksUntilIdle();
268
269 // Invalid item_ordinal and item_pin_ordinal.
270 EXPECT_TRUE(GetSyncItem(INVALID_ORDINALS_ID));
khmel 2017/06/22 00:10:12 This should be ASSERT_TRUE(GetSyncItem(INVALID_ORD
rcui 2017/06/23 02:03:49 Done. I passed on using a local var as it breaks
271 EXPECT_EQ("n",
272 GetSyncItem(INVALID_ORDINALS_ID)->item_ordinal.ToDebugString());
273 EXPECT_EQ("INVALID[$$invalid_ordinal$$]",
274 GetSyncItem(INVALID_ORDINALS_ID)->item_pin_ordinal.ToDebugString());
275
276 // Empty item name.
277 EXPECT_TRUE(GetSyncItem(EMPTY_ITEM_NAME_ID));
278 EXPECT_EQ("", GetSyncItem(EMPTY_ITEM_NAME_ID)->item_name);
279 EXPECT_TRUE(GetSyncItem(EMPTY_ITEM_NAME_UNSET_ID));
280 EXPECT_EQ("", GetSyncItem(EMPTY_ITEM_NAME_UNSET_ID)->item_name);
281
282 // Empty parent ID.
283 EXPECT_TRUE(GetSyncItem(EMPTY_PARENT_ID));
284 EXPECT_EQ("", GetSyncItem(EMPTY_PARENT_ID)->parent_id);
285 EXPECT_TRUE(GetSyncItem(EMPTY_PARENT_UNSET_ID));
286 EXPECT_EQ("", GetSyncItem(EMPTY_PARENT_UNSET_ID)->parent_id);
287
288 // Empty item_ordinal and item_pin_ordinal.
289 EXPECT_TRUE(GetSyncItem(EMPTY_ORDINALS_ID));
290 EXPECT_EQ("n", GetSyncItem(EMPTY_ORDINALS_ID)->item_ordinal.ToDebugString());
291 EXPECT_EQ("INVALID[]",
292 GetSyncItem(EMPTY_ORDINALS_ID)->item_pin_ordinal.ToDebugString());
293 EXPECT_TRUE(GetSyncItem(EMPTY_ORDINALS_UNSET_ID));
294 EXPECT_EQ("n",
295 GetSyncItem(EMPTY_ORDINALS_UNSET_ID)->item_ordinal.ToDebugString());
296 EXPECT_EQ(
297 "INVALID[]",
298 GetSyncItem(EMPTY_ORDINALS_UNSET_ID)->item_pin_ordinal.ToDebugString());
299
300 // Duplicate item_id overrides previous.
301 EXPECT_TRUE(GetSyncItem(DUPE_ITEM_ID));
302 EXPECT_EQ("item_name_dupe", GetSyncItem(DUPE_ITEM_ID)->item_name);
303 }
304
305 TEST_F(AppListSyncableServiceTest, InitialMergeAndUpdate) {
306 syncer::SyncDataList sync_list;
307 sync_list.push_back(CreateAppRemoteData(
308 "item_id1", "item_name1", "parent_id1", "ordinal", "pinordinal"));
309 sync_list.push_back(CreateAppRemoteData(
310 "item_id2", "item_name2", "parent_id2", "ordinal", "pinordinal"));
311
312 app_list_syncable_service_->MergeDataAndStartSyncing(
313 syncer::APP_LIST, sync_list,
314 std::unique_ptr<syncer::SyncChangeProcessor>(
315 new syncer::FakeSyncChangeProcessor),
316 std::unique_ptr<syncer::SyncErrorFactory>(
317 new syncer::SyncErrorFactoryMock));
318 content::RunAllBlockingPoolTasksUntilIdle();
319
320 EXPECT_TRUE(GetSyncItem("item_id1"));
321 EXPECT_TRUE(GetSyncItem("item_id2"));
322
323 syncer::SyncChangeList change_list;
324 change_list.push_back(syncer::SyncChange(
325 FROM_HERE, syncer::SyncChange::ACTION_UPDATE,
326 CreateAppRemoteData("item_id1", "item_name1x", "parent_id1x", "ordinalx",
327 "pinordinalx")));
328 change_list.push_back(syncer::SyncChange(
329 FROM_HERE, syncer::SyncChange::ACTION_UPDATE,
330 CreateAppRemoteData("item_id2", "item_name2x", "parent_id2x", "ordinalx",
331 "pinordinalx")));
332
333 app_list_syncable_service_->ProcessSyncChanges(tracked_objects::Location(),
334 change_list);
335 content::RunAllBlockingPoolTasksUntilIdle();
336
337 EXPECT_TRUE(GetSyncItem("item_id1"));
338 EXPECT_EQ("item_name1x", GetSyncItem("item_id1")->item_name);
339 EXPECT_EQ("parent_id1x", GetSyncItem("item_id1")->parent_id);
340 EXPECT_EQ("ordinalx", GetSyncItem("item_id1")->item_ordinal.ToDebugString());
341 EXPECT_EQ("pinordinalx",
342 GetSyncItem("item_id1")->item_pin_ordinal.ToDebugString());
343
344 EXPECT_TRUE(GetSyncItem("item_id2"));
345 EXPECT_EQ("item_name2x", GetSyncItem("item_id2")->item_name);
346 EXPECT_EQ("parent_id2x", GetSyncItem("item_id2")->parent_id);
347 EXPECT_EQ("ordinalx", GetSyncItem("item_id2")->item_ordinal.ToDebugString());
348 EXPECT_EQ("pinordinalx",
349 GetSyncItem("item_id2")->item_pin_ordinal.ToDebugString());
350 }
351
352 TEST_F(AppListSyncableServiceTest, InitialMergeAndUpdate_BadData) {
353 syncer::SyncDataList sync_list;
354 sync_list.push_back(CreateAppRemoteData(
355 "item_id1", "item_name1", "parent_id1", "ordinal", "pinordinal"));
356
357 app_list_syncable_service_->MergeDataAndStartSyncing(
358 syncer::APP_LIST, sync_list,
359 std::unique_ptr<syncer::SyncChangeProcessor>(
360 new syncer::FakeSyncChangeProcessor),
361 std::unique_ptr<syncer::SyncErrorFactory>(
362 new syncer::SyncErrorFactoryMock));
363 content::RunAllBlockingPoolTasksUntilIdle();
364
365 EXPECT_TRUE(GetSyncItem("item_id1"));
366
367 syncer::SyncChangeList change_list;
368 syncer::SyncDataList update_list = CreateBadAppRemoteData("item_id1");
khmel 2017/06/22 00:10:12 It is not clear what we want to achieve by sending
rcui 2017/06/23 02:03:48 I've removed the bookmark. This test should just
369 for (syncer::SyncDataList::const_iterator iter = update_list.begin();
370 iter != update_list.end(); ++iter) {
371 change_list.push_back(syncer::SyncChange(
372 FROM_HERE, syncer::SyncChange::ACTION_UPDATE, *iter));
373 }
374 // Update item that acts as a bookmark.
375 change_list.push_back(syncer::SyncChange(
376 FROM_HERE, syncer::SyncChange::ACTION_UPDATE,
377 CreateAppRemoteData("item_id1", "item_name1x", "parent_id1x", "ordinalx",
378 "pinordinalx")));
379
380 app_list_syncable_service_->ProcessSyncChanges(tracked_objects::Location(),
381 change_list);
382 content::RunAllBlockingPoolTasksUntilIdle();
383
384 EXPECT_TRUE(GetSyncItem("item_id1"));
385 // Validate all items processed by checking the last update item was
386 // processed.
387 EXPECT_EQ("item_name1x", GetSyncItem("item_id1")->item_name);
388 EXPECT_EQ("parent_id1x", GetSyncItem("item_id1")->parent_id);
389 EXPECT_EQ("ordinalx", GetSyncItem("item_id1")->item_ordinal.ToDebugString());
390 EXPECT_EQ("pinordinalx",
391 GetSyncItem("item_id1")->item_pin_ordinal.ToDebugString());
392 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698