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 "sync/engine/syncer_proto_util.h"
9 #include "base/basictypes.h"
10 #include "base/compiler_specific.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/time/time.h"
13 #include "sync/internal_api/public/base/cancelation_signal.h"
14 #include "sync/internal_api/public/base/model_type_test_util.h"
15 #include "sync/protocol/bookmark_specifics.pb.h"
16 #include "sync/protocol/password_specifics.pb.h"
17 #include "sync/protocol/sync.pb.h"
18 #include "sync/protocol/sync_enums.pb.h"
19 #include "sync/sessions/sync_session_context.h"
20 #include "sync/syncable/directory.h"
21 #include "sync/test/engine/mock_connection_manager.h"
22 #include "sync/test/engine/test_directory_setter_upper.h"
23 #include "testing/gtest/include/gtest/gtest.h"
27 using sync_pb::ClientToServerMessage
;
28 using sync_pb::CommitResponse_EntryResponse
;
29 using sync_pb::SyncEntity
;
33 using sessions::SyncSessionContext
;
35 class MockDelegate
: public sessions::SyncSession::Delegate
{
40 MOCK_METHOD1(OnReceivedShortPollIntervalUpdate
, void(const base::TimeDelta
&));
41 MOCK_METHOD1(OnReceivedLongPollIntervalUpdate
,void(const base::TimeDelta
&));
42 MOCK_METHOD1(OnReceivedSessionsCommitDelay
, void(const base::TimeDelta
&));
43 MOCK_METHOD1(OnReceivedClientInvalidationHintBufferSize
, void(int));
44 MOCK_METHOD1(OnSyncProtocolError
, void(const SyncProtocolError
&));
47 // Builds a ClientToServerResponse with some data type ids, including
48 // invalid ones. GetTypesToMigrate() should return only the valid
50 TEST(SyncerProtoUtil
, GetTypesToMigrate
) {
51 sync_pb::ClientToServerResponse response
;
52 response
.add_migrated_data_type_id(
53 GetSpecificsFieldNumberFromModelType(BOOKMARKS
));
54 response
.add_migrated_data_type_id(
55 GetSpecificsFieldNumberFromModelType(HISTORY_DELETE_DIRECTIVES
));
56 response
.add_migrated_data_type_id(-1);
58 GetTypesToMigrate(response
).Equals(
59 ModelTypeSet(BOOKMARKS
, HISTORY_DELETE_DIRECTIVES
)));
62 // Builds a ClientToServerResponse_Error with some error data type
63 // ids, including invalid ones. ConvertErrorPBToLocalType() should
64 // return a SyncProtocolError with only the valid model types.
65 TEST(SyncerProtoUtil
, ConvertErrorPBToLocalType
) {
66 sync_pb::ClientToServerResponse_Error error_pb
;
67 error_pb
.set_error_type(sync_pb::SyncEnums::THROTTLED
);
68 error_pb
.add_error_data_type_ids(
69 GetSpecificsFieldNumberFromModelType(BOOKMARKS
));
70 error_pb
.add_error_data_type_ids(
71 GetSpecificsFieldNumberFromModelType(HISTORY_DELETE_DIRECTIVES
));
72 error_pb
.add_error_data_type_ids(-1);
73 SyncProtocolError error
= ConvertErrorPBToLocalType(error_pb
);
75 error
.error_data_types
.Equals(
76 ModelTypeSet(BOOKMARKS
, HISTORY_DELETE_DIRECTIVES
)));
79 // Tests NameFromSyncEntity and NameFromCommitEntryResponse when only the name
81 TEST(SyncerProtoUtil
, NameExtractionOneName
) {
82 SyncEntity one_name_entity
;
83 CommitResponse_EntryResponse one_name_response
;
85 const std::string
one_name_string("Eggheadednesses");
86 one_name_entity
.set_name(one_name_string
);
87 one_name_response
.set_name(one_name_string
);
89 const std::string name_a
=
90 SyncerProtoUtil::NameFromSyncEntity(one_name_entity
);
91 EXPECT_EQ(one_name_string
, name_a
);
94 TEST(SyncerProtoUtil
, NameExtractionOneUniqueName
) {
95 SyncEntity one_name_entity
;
96 CommitResponse_EntryResponse one_name_response
;
98 const std::string
one_name_string("Eggheadednesses");
100 one_name_entity
.set_non_unique_name(one_name_string
);
101 one_name_response
.set_non_unique_name(one_name_string
);
103 const std::string name_a
=
104 SyncerProtoUtil::NameFromSyncEntity(one_name_entity
);
105 EXPECT_EQ(one_name_string
, name_a
);
108 // Tests NameFromSyncEntity and NameFromCommitEntryResponse when both the name
109 // field and the non_unique_name fields are provided.
110 // Should prioritize non_unique_name.
111 TEST(SyncerProtoUtil
, NameExtractionTwoNames
) {
112 SyncEntity two_name_entity
;
113 CommitResponse_EntryResponse two_name_response
;
115 const std::string
neuro("Neuroanatomists");
116 const std::string
oxyphen("Oxyphenbutazone");
118 two_name_entity
.set_name(oxyphen
);
119 two_name_entity
.set_non_unique_name(neuro
);
121 two_name_response
.set_name(oxyphen
);
122 two_name_response
.set_non_unique_name(neuro
);
124 const std::string name_a
=
125 SyncerProtoUtil::NameFromSyncEntity(two_name_entity
);
126 EXPECT_EQ(neuro
, name_a
);
129 class SyncerProtoUtilTest
: public testing::Test
{
131 void SetUp() override
{ dir_maker_
.SetUp(); }
133 void TearDown() override
{ dir_maker_
.TearDown(); }
135 syncable::Directory
* directory() {
136 return dir_maker_
.directory();
140 base::MessageLoop message_loop_
;
141 TestDirectorySetterUpper dir_maker_
;
144 TEST_F(SyncerProtoUtilTest
, VerifyResponseBirthday
) {
146 EXPECT_TRUE(directory()->store_birthday().empty());
147 sync_pb::ClientToServerResponse response
;
148 EXPECT_FALSE(SyncerProtoUtil::VerifyResponseBirthday(response
, directory()));
150 // Remote set, local empty
151 response
.set_store_birthday("flan");
152 EXPECT_TRUE(SyncerProtoUtil::VerifyResponseBirthday(response
, directory()));
153 EXPECT_EQ(directory()->store_birthday(), "flan");
155 // Remote empty, local set.
156 response
.clear_store_birthday();
157 EXPECT_TRUE(SyncerProtoUtil::VerifyResponseBirthday(response
, directory()));
158 EXPECT_EQ(directory()->store_birthday(), "flan");
161 response
.set_store_birthday("meat");
162 EXPECT_FALSE(SyncerProtoUtil::VerifyResponseBirthday(response
, directory()));
164 response
.set_error_code(sync_pb::SyncEnums::CLEAR_PENDING
);
165 EXPECT_FALSE(SyncerProtoUtil::VerifyResponseBirthday(response
, directory()));
168 TEST_F(SyncerProtoUtilTest
, VerifyDisabledByAdmin
) {
170 sync_pb::ClientToServerResponse response
;
171 EXPECT_FALSE(SyncerProtoUtil::IsSyncDisabledByAdmin(response
));
173 // Has error code, but not disabled
174 response
.set_error_code(sync_pb::SyncEnums::NOT_MY_BIRTHDAY
);
175 EXPECT_FALSE(SyncerProtoUtil::IsSyncDisabledByAdmin(response
));
177 // Has error code, and is disabled by admin
178 response
.set_error_code(sync_pb::SyncEnums::DISABLED_BY_ADMIN
);
179 EXPECT_TRUE(SyncerProtoUtil::IsSyncDisabledByAdmin(response
));
182 TEST_F(SyncerProtoUtilTest
, AddRequestBirthday
) {
183 EXPECT_TRUE(directory()->store_birthday().empty());
184 ClientToServerMessage msg
;
185 SyncerProtoUtil::AddRequestBirthday(directory(), &msg
);
186 EXPECT_FALSE(msg
.has_store_birthday());
188 directory()->set_store_birthday("meat");
189 SyncerProtoUtil::AddRequestBirthday(directory(), &msg
);
190 EXPECT_EQ(msg
.store_birthday(), "meat");
193 class DummyConnectionManager
: public ServerConnectionManager
{
195 DummyConnectionManager(CancelationSignal
* signal
)
196 : ServerConnectionManager("unused", 0, false, signal
),
198 access_denied_(false) {}
200 ~DummyConnectionManager() override
{}
201 bool PostBufferWithCachedAuth(PostBufferParams
* params
,
202 ScopedServerStatusWatcher
* watcher
) override
{
207 sync_pb::ClientToServerResponse response
;
208 if (access_denied_
) {
209 response
.set_error_code(sync_pb::SyncEnums::ACCESS_DENIED
);
211 response
.SerializeToString(¶ms
->buffer_out
);
216 void set_send_error(bool send
) {
220 void set_access_denied(bool denied
) {
221 access_denied_
= denied
;
229 TEST_F(SyncerProtoUtilTest
, PostAndProcessHeaders
) {
230 CancelationSignal signal
;
231 DummyConnectionManager
dcm(&signal
);
232 ClientToServerMessage msg
;
233 SyncerProtoUtil::SetProtocolVersion(&msg
);
234 msg
.set_share("required");
235 msg
.set_message_contents(ClientToServerMessage::GET_UPDATES
);
236 sync_pb::ClientToServerResponse response
;
238 dcm
.set_send_error(true);
239 EXPECT_FALSE(SyncerProtoUtil::PostAndProcessHeaders(&dcm
, NULL
,
242 dcm
.set_send_error(false);
243 EXPECT_TRUE(SyncerProtoUtil::PostAndProcessHeaders(&dcm
, NULL
,
246 dcm
.set_access_denied(true);
247 EXPECT_FALSE(SyncerProtoUtil::PostAndProcessHeaders(&dcm
, NULL
,
251 } // namespace syncer