1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/basictypes.h"
6 #include "sync/engine/process_updates_command.h"
7 #include "sync/engine/syncer_proto_util.h"
8 #include "sync/internal_api/public/base/model_type.h"
9 #include "sync/internal_api/public/test/test_entry_factory.h"
10 #include "sync/sessions/sync_session.h"
11 #include "sync/syncable/mutable_entry.h"
12 #include "sync/syncable/syncable_id.h"
13 #include "sync/syncable/syncable_proto_util.h"
14 #include "sync/syncable/syncable_read_transaction.h"
15 #include "sync/syncable/syncable_write_transaction.h"
16 #include "sync/test/engine/fake_model_worker.h"
17 #include "sync/test/engine/syncer_command_test.h"
18 #include "testing/gtest/include/gtest/gtest.h"
22 using sync_pb::SyncEntity
;
24 using syncable::MutableEntry
;
25 using syncable::UNITTEST
;
26 using syncable::WriteTransaction
;
30 class ProcessUpdatesCommandTest
: public SyncerCommandTest
{
32 ProcessUpdatesCommandTest() {}
33 virtual ~ProcessUpdatesCommandTest() {}
35 virtual void SetUp() {
37 make_scoped_refptr(new FakeModelWorker(GROUP_UI
)));
39 make_scoped_refptr(new FakeModelWorker(GROUP_DB
)));
40 (*mutable_routing_info())[PREFERENCES
] = GROUP_UI
;
41 (*mutable_routing_info())[BOOKMARKS
] = GROUP_UI
;
42 (*mutable_routing_info())[AUTOFILL
] = GROUP_DB
;
43 SyncerCommandTest::SetUp();
44 test_entry_factory_
.reset(new TestEntryFactory(directory()));
47 void CreateLocalItem(const std::string
& item_id
,
48 const std::string
& parent_id
,
49 const ModelType
& type
) {
50 WriteTransaction
trans(FROM_HERE
, UNITTEST
, directory());
51 MutableEntry
entry(&trans
, syncable::CREATE_NEW_UPDATE_ITEM
,
52 Id::CreateFromServerId(item_id
));
53 ASSERT_TRUE(entry
.good());
55 entry
.Put(syncable::BASE_VERSION
, 1);
56 entry
.Put(syncable::SERVER_VERSION
, 1);
57 entry
.Put(syncable::NON_UNIQUE_NAME
, item_id
);
58 entry
.Put(syncable::PARENT_ID
, Id::CreateFromServerId(parent_id
));
59 sync_pb::EntitySpecifics default_specifics
;
60 AddDefaultFieldValue(type
, &default_specifics
);
61 entry
.Put(syncable::SERVER_SPECIFICS
, default_specifics
);
64 SyncEntity
* AddUpdate(sync_pb::GetUpdatesResponse
* updates
,
65 const std::string
& id
, const std::string
& parent
,
66 const ModelType
& type
) {
67 sync_pb::SyncEntity
* e
= updates
->add_entries();
69 e
->set_parent_id_string(parent
);
70 e
->set_non_unique_name(id
);
73 AddDefaultFieldValue(type
, e
->mutable_specifics());
77 ProcessUpdatesCommand command_
;
78 scoped_ptr
<TestEntryFactory
> test_entry_factory_
;
81 DISALLOW_COPY_AND_ASSIGN(ProcessUpdatesCommandTest
);
84 TEST_F(ProcessUpdatesCommandTest
, GroupsToChange
) {
85 std::string root
= syncable::GetNullId().GetServerId();
87 CreateLocalItem("p1", root
, PREFERENCES
);
88 CreateLocalItem("a1", root
, AUTOFILL
);
90 ExpectNoGroupsToChange(command_
);
92 sync_pb::GetUpdatesResponse
* updates
=
93 session()->mutable_status_controller()->
94 mutable_updates_response()->mutable_get_updates();
95 AddUpdate(updates
, "p1", root
, PREFERENCES
);
96 AddUpdate(updates
, "a1", root
, AUTOFILL
);
98 ExpectGroupsToChange(command_
, GROUP_UI
, GROUP_DB
);
100 command_
.ExecuteImpl(session());
103 static const char kCacheGuid
[] = "IrcjZ2jyzHDV9Io4+zKcXQ==";
105 // Test that the bookmark tag is set on newly downloaded items.
106 TEST_F(ProcessUpdatesCommandTest
, NewBookmarkTag
) {
107 std::string root
= syncable::GetNullId().GetServerId();
108 sync_pb::GetUpdatesResponse
* updates
=
109 session()->mutable_status_controller()->
110 mutable_updates_response()->mutable_get_updates();
111 Id server_id
= Id::CreateFromServerId("b1");
113 AddUpdate(updates
, SyncableIdToProto(server_id
), root
, BOOKMARKS
);
115 e
->set_originator_cache_guid(
116 std::string(kCacheGuid
, arraysize(kCacheGuid
)-1));
117 Id client_id
= Id::CreateFromClientString("-2");
118 e
->set_originator_client_item_id(client_id
.GetServerId());
119 e
->set_position_in_parent(0);
121 command_
.ExecuteImpl(session());
123 syncable::ReadTransaction
trans(FROM_HERE
, directory());
124 syncable::Entry
entry(&trans
, syncable::GET_BY_ID
, server_id
);
125 ASSERT_TRUE(entry
.good());
127 UniquePosition::IsValidSuffix(entry
.Get(syncable::UNIQUE_BOOKMARK_TAG
)));
128 EXPECT_TRUE(entry
.Get(syncable::SERVER_UNIQUE_POSITION
).IsValid());
130 // If this assertion fails, that might indicate that the algorithm used to
131 // generate bookmark tags has been modified. This could have implications for
132 // bookmark ordering. Please make sure you know what you're doing if you
133 // intend to make such a change.
134 EXPECT_EQ("6wHRAb3kbnXV5GHrejp4/c1y5tw=",
135 entry
.Get(syncable::UNIQUE_BOOKMARK_TAG
));
138 TEST_F(ProcessUpdatesCommandTest
, ReceiveServerCreatedBookmarkFolders
) {
139 Id server_id
= Id::CreateFromServerId("xyz");
140 std::string root
= syncable::GetNullId().GetServerId();
141 sync_pb::GetUpdatesResponse
* updates
=
142 session()->mutable_status_controller()->
143 mutable_updates_response()->mutable_get_updates();
145 // Create an update that mimics the bookmark root.
147 AddUpdate(updates
, SyncableIdToProto(server_id
), root
, BOOKMARKS
);
148 e
->set_server_defined_unique_tag("google_chrome_bookmarks");
151 EXPECT_FALSE(SyncerProtoUtil::ShouldMaintainPosition(*e
));
153 command_
.ExecuteImpl(session());
155 syncable::ReadTransaction
trans(FROM_HERE
, directory());
156 syncable::Entry
entry(&trans
, syncable::GET_BY_ID
, server_id
);
157 ASSERT_TRUE(entry
.good());
159 EXPECT_FALSE(entry
.ShouldMaintainPosition());
160 EXPECT_FALSE(entry
.Get(syncable::UNIQUE_POSITION
).IsValid());
161 EXPECT_FALSE(entry
.Get(syncable::SERVER_UNIQUE_POSITION
).IsValid());
162 EXPECT_TRUE(entry
.Get(syncable::UNIQUE_BOOKMARK_TAG
).empty());
165 TEST_F(ProcessUpdatesCommandTest
, ReceiveNonBookmarkItem
) {
166 Id server_id
= Id::CreateFromServerId("xyz");
167 std::string root
= syncable::GetNullId().GetServerId();
168 sync_pb::GetUpdatesResponse
* updates
=
169 session()->mutable_status_controller()->
170 mutable_updates_response()->mutable_get_updates();
173 AddUpdate(updates
, SyncableIdToProto(server_id
), root
, AUTOFILL
);
174 e
->set_server_defined_unique_tag("9PGRuKdX5sHyGMB17CvYTXuC43I=");
176 EXPECT_FALSE(SyncerProtoUtil::ShouldMaintainPosition(*e
));
178 command_
.ExecuteImpl(session());
180 syncable::ReadTransaction
trans(FROM_HERE
, directory());
181 syncable::Entry
entry(&trans
, syncable::GET_BY_ID
, server_id
);
182 ASSERT_TRUE(entry
.good());
184 EXPECT_FALSE(entry
.ShouldMaintainPosition());
185 EXPECT_FALSE(entry
.Get(syncable::UNIQUE_POSITION
).IsValid());
186 EXPECT_FALSE(entry
.Get(syncable::SERVER_UNIQUE_POSITION
).IsValid());
187 EXPECT_TRUE(entry
.Get(syncable::UNIQUE_BOOKMARK_TAG
).empty());
192 } // namespace syncer