blob: 885fbe120685064566de012674ccf80aa990f29a [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/basictypes.h"
#include "sync/engine/process_updates_command.h"
#include "sync/engine/syncer_proto_util.h"
#include "sync/internal_api/public/base/model_type.h"
#include "sync/internal_api/public/test/test_entry_factory.h"
#include "sync/sessions/sync_session.h"
#include "sync/syncable/mutable_entry.h"
#include "sync/syncable/syncable_id.h"
#include "sync/syncable/syncable_proto_util.h"
#include "sync/syncable/syncable_read_transaction.h"
#include "sync/syncable/syncable_write_transaction.h"
#include "sync/test/engine/fake_model_worker.h"
#include "sync/test/engine/syncer_command_test.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace syncer {
using sync_pb::SyncEntity;
using syncable::Id;
using syncable::MutableEntry;
using syncable::UNITTEST;
using syncable::WriteTransaction;
namespace {
class ProcessUpdatesCommandTest : public SyncerCommandTest {
protected:
ProcessUpdatesCommandTest() {}
virtual ~ProcessUpdatesCommandTest() {}
virtual void SetUp() {
workers()->push_back(
make_scoped_refptr(new FakeModelWorker(GROUP_UI)));
workers()->push_back(
make_scoped_refptr(new FakeModelWorker(GROUP_DB)));
(*mutable_routing_info())[PREFERENCES] = GROUP_UI;
(*mutable_routing_info())[BOOKMARKS] = GROUP_UI;
(*mutable_routing_info())[AUTOFILL] = GROUP_DB;
SyncerCommandTest::SetUp();
test_entry_factory_.reset(new TestEntryFactory(directory()));
}
void CreateLocalItem(const std::string& item_id,
const std::string& parent_id,
const ModelType& type) {
WriteTransaction trans(FROM_HERE, UNITTEST, directory());
MutableEntry entry(&trans, syncable::CREATE_NEW_UPDATE_ITEM,
Id::CreateFromServerId(item_id));
ASSERT_TRUE(entry.good());
entry.Put(syncable::BASE_VERSION, 1);
entry.Put(syncable::SERVER_VERSION, 1);
entry.Put(syncable::NON_UNIQUE_NAME, item_id);
entry.Put(syncable::PARENT_ID, Id::CreateFromServerId(parent_id));
sync_pb::EntitySpecifics default_specifics;
AddDefaultFieldValue(type, &default_specifics);
entry.Put(syncable::SERVER_SPECIFICS, default_specifics);
}
SyncEntity* AddUpdate(sync_pb::GetUpdatesResponse* updates,
const std::string& id, const std::string& parent,
const ModelType& type) {
sync_pb::SyncEntity* e = updates->add_entries();
e->set_id_string(id);
e->set_parent_id_string(parent);
e->set_non_unique_name(id);
e->set_name(id);
e->set_version(1000);
AddDefaultFieldValue(type, e->mutable_specifics());
return e;
}
ProcessUpdatesCommand command_;
scoped_ptr<TestEntryFactory> test_entry_factory_;
private:
DISALLOW_COPY_AND_ASSIGN(ProcessUpdatesCommandTest);
};
TEST_F(ProcessUpdatesCommandTest, GroupsToChange) {
std::string root = syncable::GetNullId().GetServerId();
CreateLocalItem("p1", root, PREFERENCES);
CreateLocalItem("a1", root, AUTOFILL);
ExpectNoGroupsToChange(command_);
sync_pb::GetUpdatesResponse* updates =
session()->mutable_status_controller()->
mutable_updates_response()->mutable_get_updates();
AddUpdate(updates, "p1", root, PREFERENCES);
AddUpdate(updates, "a1", root, AUTOFILL);
ExpectGroupsToChange(command_, GROUP_UI, GROUP_DB);
command_.ExecuteImpl(session());
}
static const char kCacheGuid[] = "IrcjZ2jyzHDV9Io4+zKcXQ==";
// Test that the bookmark tag is set on newly downloaded items.
TEST_F(ProcessUpdatesCommandTest, NewBookmarkTag) {
std::string root = syncable::GetNullId().GetServerId();
sync_pb::GetUpdatesResponse* updates =
session()->mutable_status_controller()->
mutable_updates_response()->mutable_get_updates();
Id server_id = Id::CreateFromServerId("b1");
SyncEntity* e =
AddUpdate(updates, SyncableIdToProto(server_id), root, BOOKMARKS);
e->set_originator_cache_guid(
std::string(kCacheGuid, arraysize(kCacheGuid)-1));
Id client_id = Id::CreateFromClientString("-2");
e->set_originator_client_item_id(client_id.GetServerId());
e->set_position_in_parent(0);
command_.ExecuteImpl(session());
syncable::ReadTransaction trans(FROM_HERE, directory());
syncable::Entry entry(&trans, syncable::GET_BY_ID, server_id);
ASSERT_TRUE(entry.good());
EXPECT_TRUE(
UniquePosition::IsValidSuffix(entry.Get(syncable::UNIQUE_BOOKMARK_TAG)));
EXPECT_TRUE(entry.Get(syncable::SERVER_UNIQUE_POSITION).IsValid());
// If this assertion fails, that might indicate that the algorithm used to
// generate bookmark tags has been modified. This could have implications for
// bookmark ordering. Please make sure you know what you're doing if you
// intend to make such a change.
EXPECT_EQ("6wHRAb3kbnXV5GHrejp4/c1y5tw=",
entry.Get(syncable::UNIQUE_BOOKMARK_TAG));
}
TEST_F(ProcessUpdatesCommandTest, ReceiveServerCreatedBookmarkFolders) {
Id server_id = Id::CreateFromServerId("xyz");
std::string root = syncable::GetNullId().GetServerId();
sync_pb::GetUpdatesResponse* updates =
session()->mutable_status_controller()->
mutable_updates_response()->mutable_get_updates();
// Create an update that mimics the bookmark root.
SyncEntity* e =
AddUpdate(updates, SyncableIdToProto(server_id), root, BOOKMARKS);
e->set_server_defined_unique_tag("google_chrome_bookmarks");
e->set_folder(true);
EXPECT_FALSE(SyncerProtoUtil::ShouldMaintainPosition(*e));
command_.ExecuteImpl(session());
syncable::ReadTransaction trans(FROM_HERE, directory());
syncable::Entry entry(&trans, syncable::GET_BY_ID, server_id);
ASSERT_TRUE(entry.good());
EXPECT_FALSE(entry.ShouldMaintainPosition());
EXPECT_FALSE(entry.Get(syncable::UNIQUE_POSITION).IsValid());
EXPECT_FALSE(entry.Get(syncable::SERVER_UNIQUE_POSITION).IsValid());
EXPECT_TRUE(entry.Get(syncable::UNIQUE_BOOKMARK_TAG).empty());
}
TEST_F(ProcessUpdatesCommandTest, ReceiveNonBookmarkItem) {
Id server_id = Id::CreateFromServerId("xyz");
std::string root = syncable::GetNullId().GetServerId();
sync_pb::GetUpdatesResponse* updates =
session()->mutable_status_controller()->
mutable_updates_response()->mutable_get_updates();
SyncEntity* e =
AddUpdate(updates, SyncableIdToProto(server_id), root, AUTOFILL);
e->set_server_defined_unique_tag("9PGRuKdX5sHyGMB17CvYTXuC43I=");
EXPECT_FALSE(SyncerProtoUtil::ShouldMaintainPosition(*e));
command_.ExecuteImpl(session());
syncable::ReadTransaction trans(FROM_HERE, directory());
syncable::Entry entry(&trans, syncable::GET_BY_ID, server_id);
ASSERT_TRUE(entry.good());
EXPECT_FALSE(entry.ShouldMaintainPosition());
EXPECT_FALSE(entry.Get(syncable::UNIQUE_POSITION).IsValid());
EXPECT_FALSE(entry.Get(syncable::SERVER_UNIQUE_POSITION).IsValid());
EXPECT_TRUE(entry.Get(syncable::UNIQUE_BOOKMARK_TAG).empty());
}
} // namespace
} // namespace syncer