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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/ui/app_list/app_list_syncable_service_unittest.cc
diff --git a/chrome/browser/ui/app_list/app_list_syncable_service_unittest.cc b/chrome/browser/ui/app_list/app_list_syncable_service_unittest.cc
index e454e1b4cc618c35ae7170fc64a228a25fa86bd3..ca1ece8ea5c9fa867b46cee8a1c53138324fadea 100644
--- a/chrome/browser/ui/app_list/app_list_syncable_service_unittest.cc
+++ b/chrome/browser/ui/app_list/app_list_syncable_service_unittest.cc
@@ -10,11 +10,18 @@
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
#include "components/crx_file/id_util.h"
+#include "components/sync/model/attachments/attachment_service_proxy_for_test.h"
+#include "components/sync/model/fake_sync_change_processor.h"
+#include "components/sync/model/sync_error_factory.h"
+#include "components/sync/model/sync_error_factory_mock.h"
+#include "components/sync/protocol/sync.pb.h"
#include "extensions/browser/extension_system.h"
#include "extensions/common/constants.h"
#include "ui/app_list/app_list_item.h"
#include "ui/app_list/app_list_model.h"
+using namespace crx_file::id_util;
+
namespace {
scoped_refptr<extensions::Extension> MakeApp(
@@ -46,6 +53,111 @@ std::string CreateNextAppId(const std::string& app_id) {
return next_app_id;
}
+constexpr char kUnset[] = "__unset__";
+constexpr char kDefault[] = "__default__";
+
+// These constants are defined as functions so their values can be derived via
+// function calls. The constant naming scheme is kept to maintain readability.
+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.
+ return GenerateId("invalid_ordinals");
+}
+const std::string kEmptyItemNameId() {
+ return GenerateId("empty_item_name");
+}
+const std::string kEmptyItemNameUnsetId() {
+ return GenerateId("empty_item_name_unset");
+}
+const std::string kEmptyParentId() {
+ return GenerateId("empty_parent_id");
+}
+const std::string kEmptyParentUnsetId() {
+ return GenerateId("empty_parent_id_unset");
+}
+const std::string kEmptyOrdinalsId() {
+ return GenerateId("empty_ordinals");
+}
+const std::string kEmptyOrdinalsUnsetId() {
+ return GenerateId("empty_ordinals_unset");
+}
+const std::string kDupeItemId() {
+ return GenerateId("dupe_item_id");
+}
+const std::string kParentId() {
+ return GenerateId("parent_id");
+}
+
+syncer::SyncData CreateAppRemoteData(const std::string& id,
+ const std::string& name,
+ const std::string& parent_id,
+ const std::string& item_ordinal,
+ const std::string& item_pin_ordinal) {
+ sync_pb::EntitySpecifics specifics;
+ sync_pb::AppListSpecifics* app_list = specifics.mutable_app_list();
+ if (id != kUnset)
+ app_list->set_item_id(id);
+ app_list->set_item_type(sync_pb::AppListSpecifics_AppListItemType_TYPE_APP);
+ if (name != kUnset)
+ app_list->set_item_name(name);
+ if (parent_id != kUnset)
+ app_list->set_parent_id(parent_id);
+ if (item_ordinal != kUnset)
+ app_list->set_item_ordinal(item_ordinal);
+ if (item_pin_ordinal != kUnset)
+ app_list->set_item_pin_ordinal(item_pin_ordinal);
+
+ return syncer::SyncData::CreateRemoteData(
+ std::hash<std::string>{}(id), specifics, base::Time(),
+ syncer::AttachmentIdList(),
+ syncer::AttachmentServiceProxyForTest::Create());
+}
+
+syncer::SyncDataList CreateBadAppRemoteData(const std::string& id) {
+ syncer::SyncDataList sync_list;
+ // Invalid item_ordinal and item_pin_ordinal.
+ sync_list.push_back(CreateAppRemoteData(
+ id == kDefault ? kInvalidOrdinalsId() : id, "item_name", kParentId(),
+ "$$invalid_ordinal$$", "$$invalid_ordinal$$"));
+ // Empty item name.
+ sync_list.push_back(
+ CreateAppRemoteData(id == kDefault ? kEmptyItemNameId() : id, "",
+ kParentId(), "ordinal", "pinordinal"));
+ sync_list.push_back(
+ CreateAppRemoteData(id == kDefault ? kEmptyItemNameUnsetId() : id, kUnset,
+ kParentId(), "ordinal", "pinordinal"));
+ // Empty parent ID.
+ sync_list.push_back(
+ CreateAppRemoteData(id == kDefault ? kEmptyParentId() : id, "item_name",
+ "", "ordinal", "pinordinal"));
+ sync_list.push_back(
+ CreateAppRemoteData(id == kDefault ? kEmptyParentUnsetId() : id,
+ "item_name", kUnset, "ordinal", "pinordinal"));
+ // Empty item_ordinal and item_pin_ordinal.
+ sync_list.push_back(
+ CreateAppRemoteData(id == kDefault ? kEmptyOrdinalsId() : id, "item_name",
+ kParentId(), "", ""));
+ sync_list.push_back(
+ CreateAppRemoteData(id == kDefault ? kEmptyOrdinalsUnsetId() : id,
+ "item_name", kParentId(), kUnset, kUnset));
+ // Duplicate item_id.
+ sync_list.push_back(CreateAppRemoteData(id == kDefault ? kDupeItemId() : id,
+ "item_name", kParentId(), "ordinal",
+ "pinordinal"));
+ sync_list.push_back(CreateAppRemoteData(id == kDefault ? kDupeItemId() : id,
+ "item_name_dupe", kParentId(),
+ "ordinal", "pinordinal"));
+ // Empty item_id.
+ sync_list.push_back(CreateAppRemoteData("", "item_name", kParentId(),
+ "ordinal", "pinordinal"));
+ sync_list.push_back(CreateAppRemoteData(kUnset, "item_name", kParentId(),
+ "ordinal", "pinordinal"));
+ // All fields empty.
+ sync_list.push_back(CreateAppRemoteData("", "", "", "", ""));
+ sync_list.push_back(
+ CreateAppRemoteData(kUnset, kUnset, kUnset, kUnset, kUnset));
+
+ return sync_list;
+}
+
} // namespace
class AppListSyncableServiceTest : public AppListTestBase {
@@ -74,6 +186,16 @@ class AppListSyncableServiceTest : public AppListTestBase {
return app_list_syncable_service_->GetModel();
}
+ const app_list::AppListSyncableService::SyncItem* GetSyncItem(
+ const std::string& id) const {
+ return app_list_syncable_service_->GetSyncItem(id);
+ }
+
+ protected:
+ app_list::AppListSyncableService* app_list_syncable_service() {
+ return app_list_syncable_service_.get();
+ }
+
private:
base::ScopedTempDir temp_dir_;
std::unique_ptr<app_list::AppListSyncableService> app_list_syncable_service_;
@@ -131,3 +253,161 @@ TEST_F(AppListSyncableServiceTest, OEMFolderForConflictingPos) {
EXPECT_EQ(some_app_index, web_store_app_index + 1);
EXPECT_EQ(oem_folder_index, web_store_app_index + 2);
}
+
+TEST_F(AppListSyncableServiceTest, InitialMerge) {
+ const std::string kItemId1 = GenerateId("item_id1");
+ const std::string kItemId2 = GenerateId("item_id2");
+
+ syncer::SyncDataList sync_list;
+ sync_list.push_back(CreateAppRemoteData(kItemId1, "item_name1",
+ GenerateId("parent_id1"), "ordinal",
+ "pinordinal"));
+ sync_list.push_back(CreateAppRemoteData(kItemId2, "item_name2",
+ GenerateId("parent_id2"), "ordinal",
+ "pinordinal"));
+
+ app_list_syncable_service()->MergeDataAndStartSyncing(
+ syncer::APP_LIST, sync_list,
+ base::MakeUnique<syncer::FakeSyncChangeProcessor>(),
+ base::MakeUnique<syncer::SyncErrorFactoryMock>());
+ content::RunAllBlockingPoolTasksUntilIdle();
+
+ ASSERT_TRUE(GetSyncItem(kItemId1));
+ EXPECT_EQ("item_name1", GetSyncItem(kItemId1)->item_name);
+ EXPECT_EQ(GenerateId("parent_id1"), GetSyncItem(kItemId1)->parent_id);
+ EXPECT_EQ("ordinal", GetSyncItem(kItemId1)->item_ordinal.ToDebugString());
+ EXPECT_EQ("pinordinal",
+ GetSyncItem(kItemId1)->item_pin_ordinal.ToDebugString());
+
+ ASSERT_TRUE(GetSyncItem(kItemId2));
+ EXPECT_EQ("item_name2", GetSyncItem(kItemId2)->item_name);
+ EXPECT_EQ(GenerateId("parent_id2"), GetSyncItem(kItemId2)->parent_id);
+ EXPECT_EQ("ordinal", GetSyncItem(kItemId2)->item_ordinal.ToDebugString());
+ EXPECT_EQ("pinordinal",
+ GetSyncItem(kItemId2)->item_pin_ordinal.ToDebugString());
+}
+
+TEST_F(AppListSyncableServiceTest, InitialMerge_BadData) {
+ syncer::SyncDataList sync_list = CreateBadAppRemoteData(kDefault);
khmel 2017/06/23 22:37:27 nit: const syncer::...
rcui 2017/06/24 00:19:10 Done.
+
+ app_list_syncable_service()->MergeDataAndStartSyncing(
+ syncer::APP_LIST, sync_list,
+ base::MakeUnique<syncer::FakeSyncChangeProcessor>(),
+ base::MakeUnique<syncer::SyncErrorFactoryMock>());
+ content::RunAllBlockingPoolTasksUntilIdle();
+
+ // Invalid item_ordinal and item_pin_ordinal.
+ ASSERT_TRUE(GetSyncItem(kInvalidOrdinalsId()));
+ 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.
+ GetSyncItem(kInvalidOrdinalsId())->item_ordinal.ToDebugString());
+ EXPECT_EQ(
+ "INVALID[$$invalid_ordinal$$]",
+ GetSyncItem(kInvalidOrdinalsId())->item_pin_ordinal.ToDebugString());
+
+ // Empty item name.
+ ASSERT_TRUE(GetSyncItem(kEmptyItemNameId()));
+ EXPECT_EQ("", GetSyncItem(kEmptyItemNameId())->item_name);
+ EXPECT_TRUE(GetSyncItem(kEmptyItemNameUnsetId()));
+ EXPECT_EQ("", GetSyncItem(kEmptyItemNameUnsetId())->item_name);
+
+ // Empty parent ID.
+ ASSERT_TRUE(GetSyncItem(kEmptyParentId()));
+ EXPECT_EQ("", GetSyncItem(kEmptyParentId())->parent_id);
+ EXPECT_TRUE(GetSyncItem(kEmptyParentUnsetId()));
+ EXPECT_EQ("", GetSyncItem(kEmptyParentUnsetId())->parent_id);
+
+ // Empty item_ordinal and item_pin_ordinal.
+ ASSERT_TRUE(GetSyncItem(kEmptyOrdinalsId()));
+ EXPECT_EQ("n", GetSyncItem(kEmptyOrdinalsId())->item_ordinal.ToDebugString());
+ EXPECT_EQ("INVALID[]",
+ GetSyncItem(kEmptyOrdinalsId())->item_pin_ordinal.ToDebugString());
+ ASSERT_TRUE(GetSyncItem(kEmptyOrdinalsUnsetId()));
+ EXPECT_EQ("n",
+ GetSyncItem(kEmptyOrdinalsUnsetId())->item_ordinal.ToDebugString());
+ EXPECT_EQ(
+ "INVALID[]",
+ GetSyncItem(kEmptyOrdinalsUnsetId())->item_pin_ordinal.ToDebugString());
+
+ // Duplicate item_id overrides previous.
+ ASSERT_TRUE(GetSyncItem(kDupeItemId()));
+ EXPECT_EQ("item_name_dupe", GetSyncItem(kDupeItemId())->item_name);
+}
+
+TEST_F(AppListSyncableServiceTest, InitialMergeAndUpdate) {
+ const std::string kItemId1 = GenerateId("item_id1");
+ const std::string kItemId2 = GenerateId("item_id2");
+
+ syncer::SyncDataList sync_list;
+ sync_list.push_back(CreateAppRemoteData(kItemId1, "item_name1", kParentId(),
+ "ordinal", "pinordinal"));
+ sync_list.push_back(CreateAppRemoteData(kItemId2, "item_name2", kParentId(),
+ "ordinal", "pinordinal"));
+
+ app_list_syncable_service()->MergeDataAndStartSyncing(
+ syncer::APP_LIST, sync_list,
+ base::MakeUnique<syncer::FakeSyncChangeProcessor>(),
+ base::MakeUnique<syncer::SyncErrorFactoryMock>());
+ content::RunAllBlockingPoolTasksUntilIdle();
+
+ ASSERT_TRUE(GetSyncItem(kItemId1));
+ ASSERT_TRUE(GetSyncItem(kItemId2));
+
+ syncer::SyncChangeList change_list;
+ change_list.push_back(syncer::SyncChange(
+ FROM_HERE, syncer::SyncChange::ACTION_UPDATE,
+ CreateAppRemoteData(kItemId1, "item_name1x", GenerateId("parent_id1x"),
+ "ordinalx", "pinordinalx")));
+ change_list.push_back(syncer::SyncChange(
+ FROM_HERE, syncer::SyncChange::ACTION_UPDATE,
+ CreateAppRemoteData(kItemId2, "item_name2x", GenerateId("parent_id2x"),
+ "ordinalx", "pinordinalx")));
+
+ app_list_syncable_service()->ProcessSyncChanges(tracked_objects::Location(),
+ change_list);
+ content::RunAllBlockingPoolTasksUntilIdle();
+
+ ASSERT_TRUE(GetSyncItem(kItemId1));
+ 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
+ EXPECT_EQ(GenerateId("parent_id1x"), GetSyncItem(kItemId1)->parent_id);
+ EXPECT_EQ("ordinalx", GetSyncItem(kItemId1)->item_ordinal.ToDebugString());
+ EXPECT_EQ("pinordinalx",
+ GetSyncItem(kItemId1)->item_pin_ordinal.ToDebugString());
+
+ ASSERT_TRUE(GetSyncItem(kItemId2));
+ EXPECT_EQ("item_name2x", GetSyncItem(kItemId2)->item_name);
+ EXPECT_EQ(GenerateId("parent_id2x"), GetSyncItem(kItemId2)->parent_id);
+ EXPECT_EQ("ordinalx", GetSyncItem(kItemId2)->item_ordinal.ToDebugString());
+ EXPECT_EQ("pinordinalx",
+ GetSyncItem(kItemId2)->item_pin_ordinal.ToDebugString());
+}
+
+TEST_F(AppListSyncableServiceTest, InitialMergeAndUpdate_BadData) {
+ const std::string kItemId = GenerateId("item_id");
+
+ syncer::SyncDataList sync_list;
+ sync_list.push_back(CreateAppRemoteData(kItemId, "item_name", kParentId(),
+ "ordinal", "pinordinal"));
+
+ app_list_syncable_service()->MergeDataAndStartSyncing(
+ syncer::APP_LIST, sync_list,
+ base::MakeUnique<syncer::FakeSyncChangeProcessor>(),
+ base::MakeUnique<syncer::SyncErrorFactoryMock>());
+ content::RunAllBlockingPoolTasksUntilIdle();
+
+ ASSERT_TRUE(GetSyncItem(kItemId));
+
+ syncer::SyncChangeList change_list;
+ syncer::SyncDataList update_list = CreateBadAppRemoteData(kItemId);
+ for (syncer::SyncDataList::const_iterator iter = update_list.begin();
+ iter != update_list.end(); ++iter) {
+ change_list.push_back(syncer::SyncChange(
+ FROM_HERE, syncer::SyncChange::ACTION_UPDATE, *iter));
+ }
+
+ // Validate items with bad data are processed without crashing.
+ app_list_syncable_service()->ProcessSyncChanges(tracked_objects::Location(),
+ change_list);
+ content::RunAllBlockingPoolTasksUntilIdle();
+
+ 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.
+}
« 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