diff options
-rw-r--r-- | sync/engine/commit_util.cc | 4 | ||||
-rw-r--r-- | sync/engine/directory_commit_contribution_unittest.cc | 103 | ||||
-rw-r--r-- | sync/protocol/sync.proto | 2 | ||||
-rw-r--r-- | sync/syncable/model_type_unittest.cc | 21 |
4 files changed, 129 insertions, 1 deletions
diff --git a/sync/engine/commit_util.cc b/sync/engine/commit_util.cc index 45bc2bb..36b7c06 100644 --- a/sync/engine/commit_util.cc +++ b/sync/engine/commit_util.cc @@ -182,6 +182,10 @@ void BuildCommitItem( // Deletion is final on the server, let's move things and then delete them. if (meta_entry.GetIsDel()) { sync_entry->set_deleted(true); + + sync_pb::EntitySpecifics type_only_specifics; + AddDefaultFieldValue(meta_entry.GetModelType(), + sync_entry->mutable_specifics()); } else { SetEntrySpecifics(meta_entry, sync_entry); } diff --git a/sync/engine/directory_commit_contribution_unittest.cc b/sync/engine/directory_commit_contribution_unittest.cc index c38af19..475985c 100644 --- a/sync/engine/directory_commit_contribution_unittest.cc +++ b/sync/engine/directory_commit_contribution_unittest.cc @@ -25,6 +25,7 @@ class DirectoryCommitContributionTest : public ::testing::Test { syncable::WriteTransaction trans(FROM_HERE, syncable::UNITTEST, dir()); CreateTypeRoot(&trans, dir(), PREFERENCES); CreateTypeRoot(&trans, dir(), EXTENSIONS); + CreateTypeRoot(&trans, dir(), BOOKMARKS); } virtual void TearDown() OVERRIDE { @@ -49,6 +50,32 @@ class DirectoryCommitContributionTest : public ::testing::Test { return entry.GetMetahandle(); } + int64 CreateSyncedItem(syncable::WriteTransaction* trans, + ModelType type, + const std::string& tag) { + syncable::Entry parent_entry( + trans, + syncable::GET_BY_SERVER_TAG, + ModelTypeToRootTag(type)); + syncable::MutableEntry entry( + trans, + syncable::CREATE, + type, + parent_entry.GetId(), + tag); + + entry.PutId(syncable::Id::CreateFromServerId( + id_factory_.NewServerId().GetServerId())); + entry.PutBaseVersion(10); + entry.PutServerVersion(10); + entry.PutIsUnappliedUpdate(false); + entry.PutIsUnsynced(false); + entry.PutIsDel(false); + entry.PutServerIsDel(false); + + return entry.GetMetahandle(); + } + void CreateSuccessfulCommitResponse( const sync_pb::SyncEntity& entity, sync_pb::CommitResponse::EntryResponse* response) { @@ -177,6 +204,82 @@ TEST_F(DirectoryCommitContributionTest, PrepareCommit) { ext_cc->CleanUp(); } +// Check that deletion requests include a model type. +// This was not always the case, but was implemented to allow us to loosen some +// other restrictions in the protocol. +TEST_F(DirectoryCommitContributionTest, DeletedItemsWithSpecifics) { + int64 pref1; + { + syncable::WriteTransaction trans(FROM_HERE, syncable::UNITTEST, dir()); + pref1 = CreateSyncedItem(&trans, PREFERENCES, "pref1"); + syncable::MutableEntry e1(&trans, syncable::GET_BY_HANDLE, pref1); + e1.PutIsDel(true); + e1.PutIsUnsynced(true); + } + + DirectoryTypeDebugInfoEmitter emitter(PREFERENCES, &type_observers_); + scoped_ptr<DirectoryCommitContribution> pref_cc( + DirectoryCommitContribution::Build(dir(), PREFERENCES, 25, &emitter)); + ASSERT_TRUE(pref_cc); + + sync_pb::ClientToServerMessage message; + pref_cc->AddToCommitMessage(&message); + + const sync_pb::CommitMessage& commit_message = message.commit(); + ASSERT_EQ(1, commit_message.entries_size()); + EXPECT_TRUE( + commit_message.entries(0).specifics().has_preference()); + + pref_cc->CleanUp(); +} + +// As ususal, bookmarks are special. Bookmark deletion is special. +// Deleted bookmarks include a valid "is folder" bit and their full specifics +// (especially the meta info, which is what server really wants). +TEST_F(DirectoryCommitContributionTest, DeletedBookmarksWithSpecifics) { + int64 bm1; + { + syncable::WriteTransaction trans(FROM_HERE, syncable::UNITTEST, dir()); + bm1 = CreateSyncedItem(&trans, BOOKMARKS, "bm1"); + syncable::MutableEntry e1(&trans, syncable::GET_BY_HANDLE, bm1); + + e1.PutIsDir(true); + e1.PutServerIsDir(true); + + sync_pb::EntitySpecifics specifics; + sync_pb::BookmarkSpecifics* bm_specifics = specifics.mutable_bookmark(); + bm_specifics->set_url("http://www.chrome.com"); + bm_specifics->set_title("Chrome"); + sync_pb::MetaInfo* meta_info = bm_specifics->add_meta_info(); + meta_info->set_key("K"); + meta_info->set_value("V"); + e1.PutSpecifics(specifics); + + e1.PutIsDel(true); + e1.PutIsUnsynced(true); + } + + DirectoryTypeDebugInfoEmitter emitter(BOOKMARKS, &type_observers_); + scoped_ptr<DirectoryCommitContribution> bm_cc( + DirectoryCommitContribution::Build(dir(), BOOKMARKS, 25, &emitter)); + ASSERT_TRUE(bm_cc); + + sync_pb::ClientToServerMessage message; + bm_cc->AddToCommitMessage(&message); + + const sync_pb::CommitMessage& commit_message = message.commit(); + ASSERT_EQ(1, commit_message.entries_size()); + + const sync_pb::SyncEntity& entity = commit_message.entries(0); + EXPECT_TRUE(entity.has_folder()); + ASSERT_TRUE(entity.specifics().has_bookmark()); + ASSERT_EQ(1, entity.specifics().bookmark().meta_info_size()); + EXPECT_EQ("K", entity.specifics().bookmark().meta_info(0).key()); + EXPECT_EQ("V", entity.specifics().bookmark().meta_info(0).value()); + + bm_cc->CleanUp(); +} + // Creates some unsynced items, pretends to commit them, and hands back a // specially crafted response to the syncer in order to test commit response // processing. The response simulates a succesful commit scenario. diff --git a/sync/protocol/sync.proto b/sync/protocol/sync.proto index 1e9b66a..2768242 100644 --- a/sync/protocol/sync.proto +++ b/sync/protocol/sync.proto @@ -692,7 +692,7 @@ message DataTypeContext { message ClientToServerMessage { required string share = 1; - optional int32 protocol_version = 2 [default = 32]; + optional int32 protocol_version = 2 [default = 33]; enum Contents { COMMIT = 1; GET_UPDATES = 2; diff --git a/sync/syncable/model_type_unittest.cc b/sync/syncable/model_type_unittest.cc index 3ac9fd116..7bf50e5 100644 --- a/sync/syncable/model_type_unittest.cc +++ b/sync/syncable/model_type_unittest.cc @@ -9,6 +9,7 @@ #include "base/memory/scoped_ptr.h" #include "base/test/values_test_util.h" #include "base/values.h" +#include "sync/protocol/sync.pb.h" #include "testing/gtest/include/gtest/gtest.h" namespace syncer { @@ -117,5 +118,25 @@ TEST_F(ModelTypeTest, ModelTypeSetFromString) { two.Equals(ModelTypeSetFromString(ModelTypeSetToString(two)))); } +TEST_F(ModelTypeTest, DefaultFieldValues) { + syncer::ModelTypeSet types = syncer::ProtocolTypes(); + for (ModelTypeSet::Iterator it = types.First(); it.Good(); it.Inc()) { + SCOPED_TRACE(ModelTypeToString(it.Get())); + + sync_pb::EntitySpecifics specifics; + syncer::AddDefaultFieldValue(it.Get(), &specifics); + EXPECT_TRUE(specifics.IsInitialized()); + + std::string tmp; + EXPECT_TRUE(specifics.SerializeToString(&tmp)); + + sync_pb::EntitySpecifics from_string; + EXPECT_TRUE(from_string.ParseFromString(tmp)); + EXPECT_TRUE(from_string.IsInitialized()); + + EXPECT_EQ(it.Get(), syncer::GetModelTypeFromSpecifics(from_string)); + } +} + } // namespace } // namespace syncer |