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

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
23 using namespace crx_file::id_util;
24
18 namespace { 25 namespace {
19 26
20 scoped_refptr<extensions::Extension> MakeApp( 27 scoped_refptr<extensions::Extension> MakeApp(
21 const std::string& name, 28 const std::string& name,
22 const std::string& id, 29 const std::string& id,
23 extensions::Extension::InitFromValueFlags flags) { 30 extensions::Extension::InitFromValueFlags flags) {
24 std::string err; 31 std::string err;
25 base::DictionaryValue value; 32 base::DictionaryValue value;
26 value.SetString("name", name); 33 value.SetString("name", name);
27 value.SetString("version", "0.0"); 34 value.SetString("version", "0.0");
(...skipping 11 matching lines...) Expand all
39 std::string next_app_id = app_id; 46 std::string next_app_id = app_id;
40 size_t index = next_app_id.length() - 1; 47 size_t index = next_app_id.length() - 1;
41 while (index > 0 && next_app_id[index] == 'p') 48 while (index > 0 && next_app_id[index] == 'p')
42 next_app_id[index--] = 'a'; 49 next_app_id[index--] = 'a';
43 DCHECK(next_app_id[index] != 'p'); 50 DCHECK(next_app_id[index] != 'p');
44 next_app_id[index]++; 51 next_app_id[index]++;
45 DCHECK(crx_file::id_util::IdIsValid(next_app_id)); 52 DCHECK(crx_file::id_util::IdIsValid(next_app_id));
46 return next_app_id; 53 return next_app_id;
47 } 54 }
48 55
56 constexpr char kUnset[] = "__unset__";
57 constexpr char kDefault[] = "__default__";
58
59 // These constants are defined as functions so their values can be derived via
60 // function calls. The constant naming scheme is kept to maintain readability.
61 const std::string kInvalidOrdinalsId() {
khmel 2017/06/23 22:37:27 nit: it seems const here does not make sense. You
rcui 2017/06/24 00:19:10 Keeping the const, as it maintains consistency wit
khmel 2017/06/24 00:30:16 Acknowledged.
62 return GenerateId("invalid_ordinals");
63 }
64 const std::string kEmptyItemNameId() {
65 return GenerateId("empty_item_name");
66 }
67 const std::string kEmptyItemNameUnsetId() {
68 return GenerateId("empty_item_name_unset");
69 }
70 const std::string kEmptyParentId() {
71 return GenerateId("empty_parent_id");
72 }
73 const std::string kEmptyParentUnsetId() {
74 return GenerateId("empty_parent_id_unset");
75 }
76 const std::string kEmptyOrdinalsId() {
77 return GenerateId("empty_ordinals");
78 }
79 const std::string kEmptyOrdinalsUnsetId() {
80 return GenerateId("empty_ordinals_unset");
81 }
82 const std::string kDupeItemId() {
83 return GenerateId("dupe_item_id");
84 }
85 const std::string kParentId() {
86 return GenerateId("parent_id");
87 }
88
89 syncer::SyncData CreateAppRemoteData(const std::string& id,
90 const std::string& name,
91 const std::string& parent_id,
92 const std::string& item_ordinal,
93 const std::string& item_pin_ordinal) {
94 sync_pb::EntitySpecifics specifics;
95 sync_pb::AppListSpecifics* app_list = specifics.mutable_app_list();
96 if (id != kUnset)
97 app_list->set_item_id(id);
98 app_list->set_item_type(sync_pb::AppListSpecifics_AppListItemType_TYPE_APP);
99 if (name != kUnset)
100 app_list->set_item_name(name);
101 if (parent_id != kUnset)
102 app_list->set_parent_id(parent_id);
103 if (item_ordinal != kUnset)
104 app_list->set_item_ordinal(item_ordinal);
105 if (item_pin_ordinal != kUnset)
106 app_list->set_item_pin_ordinal(item_pin_ordinal);
107
108 return syncer::SyncData::CreateRemoteData(
109 std::hash<std::string>{}(id), specifics, base::Time(),
110 syncer::AttachmentIdList(),
111 syncer::AttachmentServiceProxyForTest::Create());
112 }
113
114 syncer::SyncDataList CreateBadAppRemoteData(const std::string& id) {
115 syncer::SyncDataList sync_list;
116 // Invalid item_ordinal and item_pin_ordinal.
117 sync_list.push_back(CreateAppRemoteData(
118 id == kDefault ? kInvalidOrdinalsId() : id, "item_name", kParentId(),
119 "$$invalid_ordinal$$", "$$invalid_ordinal$$"));
120 // Empty item name.
121 sync_list.push_back(
122 CreateAppRemoteData(id == kDefault ? kEmptyItemNameId() : id, "",
123 kParentId(), "ordinal", "pinordinal"));
124 sync_list.push_back(
125 CreateAppRemoteData(id == kDefault ? kEmptyItemNameUnsetId() : id, kUnset,
126 kParentId(), "ordinal", "pinordinal"));
127 // Empty parent ID.
128 sync_list.push_back(
129 CreateAppRemoteData(id == kDefault ? kEmptyParentId() : id, "item_name",
130 "", "ordinal", "pinordinal"));
131 sync_list.push_back(
132 CreateAppRemoteData(id == kDefault ? kEmptyParentUnsetId() : id,
133 "item_name", kUnset, "ordinal", "pinordinal"));
134 // Empty item_ordinal and item_pin_ordinal.
135 sync_list.push_back(
136 CreateAppRemoteData(id == kDefault ? kEmptyOrdinalsId() : id, "item_name",
137 kParentId(), "", ""));
138 sync_list.push_back(
139 CreateAppRemoteData(id == kDefault ? kEmptyOrdinalsUnsetId() : id,
140 "item_name", kParentId(), kUnset, kUnset));
141 // Duplicate item_id.
142 sync_list.push_back(CreateAppRemoteData(id == kDefault ? kDupeItemId() : id,
143 "item_name", kParentId(), "ordinal",
144 "pinordinal"));
145 sync_list.push_back(CreateAppRemoteData(id == kDefault ? kDupeItemId() : id,
146 "item_name_dupe", kParentId(),
147 "ordinal", "pinordinal"));
148 // Empty item_id.
149 sync_list.push_back(CreateAppRemoteData("", "item_name", kParentId(),
150 "ordinal", "pinordinal"));
151 sync_list.push_back(CreateAppRemoteData(kUnset, "item_name", kParentId(),
152 "ordinal", "pinordinal"));
153 // All fields empty.
154 sync_list.push_back(CreateAppRemoteData("", "", "", "", ""));
155 sync_list.push_back(
156 CreateAppRemoteData(kUnset, kUnset, kUnset, kUnset, kUnset));
157
158 return sync_list;
159 }
160
49 } // namespace 161 } // namespace
50 162
51 class AppListSyncableServiceTest : public AppListTestBase { 163 class AppListSyncableServiceTest : public AppListTestBase {
52 public: 164 public:
53 AppListSyncableServiceTest() = default; 165 AppListSyncableServiceTest() = default;
54 ~AppListSyncableServiceTest() override = default; 166 ~AppListSyncableServiceTest() override = default;
55 167
56 void SetUp() override { 168 void SetUp() override {
57 AppListTestBase::SetUp(); 169 AppListTestBase::SetUp();
58 170
59 // Make sure we have a Profile Manager. 171 // Make sure we have a Profile Manager.
60 DCHECK(temp_dir_.CreateUniqueTempDir()); 172 DCHECK(temp_dir_.CreateUniqueTempDir());
61 TestingBrowserProcess::GetGlobal()->SetProfileManager( 173 TestingBrowserProcess::GetGlobal()->SetProfileManager(
62 new ProfileManagerWithoutInit(temp_dir_.GetPath())); 174 new ProfileManagerWithoutInit(temp_dir_.GetPath()));
63 175
64 extensions::ExtensionSystem* extension_system = 176 extensions::ExtensionSystem* extension_system =
65 extensions::ExtensionSystem::Get(profile_.get()); 177 extensions::ExtensionSystem::Get(profile_.get());
66 DCHECK(extension_system); 178 DCHECK(extension_system);
67 app_list_syncable_service_.reset( 179 app_list_syncable_service_.reset(
68 new app_list::AppListSyncableService(profile_.get(), extension_system)); 180 new app_list::AppListSyncableService(profile_.get(), extension_system));
69 } 181 }
70 182
71 void TearDown() override { app_list_syncable_service_.reset(); } 183 void TearDown() override { app_list_syncable_service_.reset(); }
72 184
73 app_list::AppListModel* model() { 185 app_list::AppListModel* model() {
74 return app_list_syncable_service_->GetModel(); 186 return app_list_syncable_service_->GetModel();
75 } 187 }
76 188
189 const app_list::AppListSyncableService::SyncItem* GetSyncItem(
190 const std::string& id) const {
191 return app_list_syncable_service_->GetSyncItem(id);
192 }
193
194 protected:
195 app_list::AppListSyncableService* app_list_syncable_service() {
196 return app_list_syncable_service_.get();
197 }
198
77 private: 199 private:
78 base::ScopedTempDir temp_dir_; 200 base::ScopedTempDir temp_dir_;
79 std::unique_ptr<app_list::AppListSyncableService> app_list_syncable_service_; 201 std::unique_ptr<app_list::AppListSyncableService> app_list_syncable_service_;
80 202
81 DISALLOW_COPY_AND_ASSIGN(AppListSyncableServiceTest); 203 DISALLOW_COPY_AND_ASSIGN(AppListSyncableServiceTest);
82 }; 204 };
83 205
84 TEST_F(AppListSyncableServiceTest, OEMFolderForConflictingPos) { 206 TEST_F(AppListSyncableServiceTest, OEMFolderForConflictingPos) {
85 // Create a "web store" app. 207 // Create a "web store" app.
86 const std::string web_store_app_id(extensions::kWebStoreAppId); 208 const std::string web_store_app_id(extensions::kWebStoreAppId);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 EXPECT_FALSE(model()->top_level_item_list()->FindItemIndex(oem_app_id, 246 EXPECT_FALSE(model()->top_level_item_list()->FindItemIndex(oem_app_id,
125 &oem_app_index)); 247 &oem_app_index));
126 // But OEM folder is. 248 // But OEM folder is.
127 EXPECT_TRUE(model()->top_level_item_list()->FindItemIndex( 249 EXPECT_TRUE(model()->top_level_item_list()->FindItemIndex(
128 app_list::AppListSyncableService::kOemFolderId, &oem_folder_index)); 250 app_list::AppListSyncableService::kOemFolderId, &oem_folder_index));
129 251
130 // Ensure right item sequence. 252 // Ensure right item sequence.
131 EXPECT_EQ(some_app_index, web_store_app_index + 1); 253 EXPECT_EQ(some_app_index, web_store_app_index + 1);
132 EXPECT_EQ(oem_folder_index, web_store_app_index + 2); 254 EXPECT_EQ(oem_folder_index, web_store_app_index + 2);
133 } 255 }
256
257 TEST_F(AppListSyncableServiceTest, InitialMerge) {
258 const std::string kItemId1 = GenerateId("item_id1");
259 const std::string kItemId2 = GenerateId("item_id2");
260
261 syncer::SyncDataList sync_list;
262 sync_list.push_back(CreateAppRemoteData(kItemId1, "item_name1",
263 GenerateId("parent_id1"), "ordinal",
264 "pinordinal"));
265 sync_list.push_back(CreateAppRemoteData(kItemId2, "item_name2",
266 GenerateId("parent_id2"), "ordinal",
267 "pinordinal"));
268
269 app_list_syncable_service()->MergeDataAndStartSyncing(
270 syncer::APP_LIST, sync_list,
271 base::MakeUnique<syncer::FakeSyncChangeProcessor>(),
272 base::MakeUnique<syncer::SyncErrorFactoryMock>());
273 content::RunAllBlockingPoolTasksUntilIdle();
274
275 ASSERT_TRUE(GetSyncItem(kItemId1));
276 EXPECT_EQ("item_name1", GetSyncItem(kItemId1)->item_name);
277 EXPECT_EQ(GenerateId("parent_id1"), GetSyncItem(kItemId1)->parent_id);
278 EXPECT_EQ("ordinal", GetSyncItem(kItemId1)->item_ordinal.ToDebugString());
279 EXPECT_EQ("pinordinal",
280 GetSyncItem(kItemId1)->item_pin_ordinal.ToDebugString());
281
282 ASSERT_TRUE(GetSyncItem(kItemId2));
283 EXPECT_EQ("item_name2", GetSyncItem(kItemId2)->item_name);
284 EXPECT_EQ(GenerateId("parent_id2"), GetSyncItem(kItemId2)->parent_id);
285 EXPECT_EQ("ordinal", GetSyncItem(kItemId2)->item_ordinal.ToDebugString());
286 EXPECT_EQ("pinordinal",
287 GetSyncItem(kItemId2)->item_pin_ordinal.ToDebugString());
288 }
289
290 TEST_F(AppListSyncableServiceTest, InitialMerge_BadData) {
291 syncer::SyncDataList sync_list = CreateBadAppRemoteData(kDefault);
khmel 2017/06/23 22:37:27 nit: const syncer::...
rcui 2017/06/24 00:19:10 Done.
292
293 app_list_syncable_service()->MergeDataAndStartSyncing(
294 syncer::APP_LIST, sync_list,
295 base::MakeUnique<syncer::FakeSyncChangeProcessor>(),
296 base::MakeUnique<syncer::SyncErrorFactoryMock>());
297 content::RunAllBlockingPoolTasksUntilIdle();
298
299 // Invalid item_ordinal and item_pin_ordinal.
300 ASSERT_TRUE(GetSyncItem(kInvalidOrdinalsId()));
301 EXPECT_EQ("n",
khmel 2017/06/23 22:37:27 nit: It is not clear that "n" represents initial v
rcui 2017/06/24 00:19:10 With tests, I think it's good to be as literal as
khmel 2017/06/24 00:30:16 Acknowledged.
302 GetSyncItem(kInvalidOrdinalsId())->item_ordinal.ToDebugString());
303 EXPECT_EQ(
304 "INVALID[$$invalid_ordinal$$]",
305 GetSyncItem(kInvalidOrdinalsId())->item_pin_ordinal.ToDebugString());
306
307 // Empty item name.
308 ASSERT_TRUE(GetSyncItem(kEmptyItemNameId()));
309 EXPECT_EQ("", GetSyncItem(kEmptyItemNameId())->item_name);
310 EXPECT_TRUE(GetSyncItem(kEmptyItemNameUnsetId()));
311 EXPECT_EQ("", GetSyncItem(kEmptyItemNameUnsetId())->item_name);
312
313 // Empty parent ID.
314 ASSERT_TRUE(GetSyncItem(kEmptyParentId()));
315 EXPECT_EQ("", GetSyncItem(kEmptyParentId())->parent_id);
316 EXPECT_TRUE(GetSyncItem(kEmptyParentUnsetId()));
317 EXPECT_EQ("", GetSyncItem(kEmptyParentUnsetId())->parent_id);
318
319 // Empty item_ordinal and item_pin_ordinal.
320 ASSERT_TRUE(GetSyncItem(kEmptyOrdinalsId()));
321 EXPECT_EQ("n", GetSyncItem(kEmptyOrdinalsId())->item_ordinal.ToDebugString());
322 EXPECT_EQ("INVALID[]",
323 GetSyncItem(kEmptyOrdinalsId())->item_pin_ordinal.ToDebugString());
324 ASSERT_TRUE(GetSyncItem(kEmptyOrdinalsUnsetId()));
325 EXPECT_EQ("n",
326 GetSyncItem(kEmptyOrdinalsUnsetId())->item_ordinal.ToDebugString());
327 EXPECT_EQ(
328 "INVALID[]",
329 GetSyncItem(kEmptyOrdinalsUnsetId())->item_pin_ordinal.ToDebugString());
330
331 // Duplicate item_id overrides previous.
332 ASSERT_TRUE(GetSyncItem(kDupeItemId()));
333 EXPECT_EQ("item_name_dupe", GetSyncItem(kDupeItemId())->item_name);
334 }
335
336 TEST_F(AppListSyncableServiceTest, InitialMergeAndUpdate) {
337 const std::string kItemId1 = GenerateId("item_id1");
338 const std::string kItemId2 = GenerateId("item_id2");
339
340 syncer::SyncDataList sync_list;
341 sync_list.push_back(CreateAppRemoteData(kItemId1, "item_name1", kParentId(),
342 "ordinal", "pinordinal"));
343 sync_list.push_back(CreateAppRemoteData(kItemId2, "item_name2", kParentId(),
344 "ordinal", "pinordinal"));
345
346 app_list_syncable_service()->MergeDataAndStartSyncing(
347 syncer::APP_LIST, sync_list,
348 base::MakeUnique<syncer::FakeSyncChangeProcessor>(),
349 base::MakeUnique<syncer::SyncErrorFactoryMock>());
350 content::RunAllBlockingPoolTasksUntilIdle();
351
352 ASSERT_TRUE(GetSyncItem(kItemId1));
353 ASSERT_TRUE(GetSyncItem(kItemId2));
354
355 syncer::SyncChangeList change_list;
356 change_list.push_back(syncer::SyncChange(
357 FROM_HERE, syncer::SyncChange::ACTION_UPDATE,
358 CreateAppRemoteData(kItemId1, "item_name1x", GenerateId("parent_id1x"),
359 "ordinalx", "pinordinalx")));
360 change_list.push_back(syncer::SyncChange(
361 FROM_HERE, syncer::SyncChange::ACTION_UPDATE,
362 CreateAppRemoteData(kItemId2, "item_name2x", GenerateId("parent_id2x"),
363 "ordinalx", "pinordinalx")));
364
365 app_list_syncable_service()->ProcessSyncChanges(tracked_objects::Location(),
366 change_list);
367 content::RunAllBlockingPoolTasksUntilIdle();
368
369 ASSERT_TRUE(GetSyncItem(kItemId1));
370 EXPECT_EQ("item_name1x", GetSyncItem(kItemId1)->item_name);
khmel 2017/06/23 22:37:27 nit: It seems you frequently use this pattern. If
rcui 2017/06/24 00:19:10 I went ahead and tried it, and the issue with this
khmel 2017/06/24 00:30:16 Usually this is not a problem. For example: https:
rcui 2017/06/24 01:01:54 It does seem like it'll make tests harder to maint
371 EXPECT_EQ(GenerateId("parent_id1x"), GetSyncItem(kItemId1)->parent_id);
372 EXPECT_EQ("ordinalx", GetSyncItem(kItemId1)->item_ordinal.ToDebugString());
373 EXPECT_EQ("pinordinalx",
374 GetSyncItem(kItemId1)->item_pin_ordinal.ToDebugString());
375
376 ASSERT_TRUE(GetSyncItem(kItemId2));
377 EXPECT_EQ("item_name2x", GetSyncItem(kItemId2)->item_name);
378 EXPECT_EQ(GenerateId("parent_id2x"), GetSyncItem(kItemId2)->parent_id);
379 EXPECT_EQ("ordinalx", GetSyncItem(kItemId2)->item_ordinal.ToDebugString());
380 EXPECT_EQ("pinordinalx",
381 GetSyncItem(kItemId2)->item_pin_ordinal.ToDebugString());
382 }
383
384 TEST_F(AppListSyncableServiceTest, InitialMergeAndUpdate_BadData) {
385 const std::string kItemId = GenerateId("item_id");
386
387 syncer::SyncDataList sync_list;
388 sync_list.push_back(CreateAppRemoteData(kItemId, "item_name", kParentId(),
389 "ordinal", "pinordinal"));
390
391 app_list_syncable_service()->MergeDataAndStartSyncing(
392 syncer::APP_LIST, sync_list,
393 base::MakeUnique<syncer::FakeSyncChangeProcessor>(),
394 base::MakeUnique<syncer::SyncErrorFactoryMock>());
395 content::RunAllBlockingPoolTasksUntilIdle();
396
397 ASSERT_TRUE(GetSyncItem(kItemId));
398
399 syncer::SyncChangeList change_list;
400 syncer::SyncDataList update_list = CreateBadAppRemoteData(kItemId);
401 for (syncer::SyncDataList::const_iterator iter = update_list.begin();
402 iter != update_list.end(); ++iter) {
403 change_list.push_back(syncer::SyncChange(
404 FROM_HERE, syncer::SyncChange::ACTION_UPDATE, *iter));
405 }
406
407 // Validate items with bad data are processed without crashing.
408 app_list_syncable_service()->ProcessSyncChanges(tracked_objects::Location(),
409 change_list);
410 content::RunAllBlockingPoolTasksUntilIdle();
411
412 ASSERT_TRUE(GetSyncItem(kItemId));
khmel 2017/06/23 22:37:27 nit: it would be nice to check that sync item was
rcui 2017/06/24 00:19:11 Given the type of bad data we're using, the sync i
khmel 2017/06/24 00:30:16 Up to you, I just wanted to see the use case when
rcui 2017/06/24 01:01:54 Acknowledged.
413 }
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