OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "sync/engine/syncer_proto_util.h" | |
6 | |
7 #include <string> | |
8 | |
9 #include "base/compiler_specific.h" | |
10 #include "base/message_loop/message_loop.h" | |
11 #include "base/time/time.h" | |
12 #include "sync/internal_api/public/base/cancelation_signal.h" | |
13 #include "sync/internal_api/public/base/model_type_test_util.h" | |
14 #include "sync/protocol/bookmark_specifics.pb.h" | |
15 #include "sync/protocol/password_specifics.pb.h" | |
16 #include "sync/protocol/sync.pb.h" | |
17 #include "sync/protocol/sync_enums.pb.h" | |
18 #include "sync/sessions/sync_session_context.h" | |
19 #include "sync/syncable/directory.h" | |
20 #include "sync/test/engine/mock_connection_manager.h" | |
21 #include "sync/test/engine/test_directory_setter_upper.h" | |
22 #include "testing/gtest/include/gtest/gtest.h" | |
23 | |
24 using ::testing::_; | |
25 | |
26 using sync_pb::ClientToServerMessage; | |
27 using sync_pb::CommitResponse_EntryResponse; | |
28 using sync_pb::SyncEntity; | |
29 | |
30 namespace syncer { | |
31 | |
32 using sessions::SyncSessionContext; | |
33 | |
34 class MockDelegate : public sessions::SyncSession::Delegate { | |
35 public: | |
36 MockDelegate() {} | |
37 ~MockDelegate() {} | |
38 | |
39 MOCK_METHOD1(OnReceivedShortPollIntervalUpdate, void(const base::TimeDelta&)); | |
40 MOCK_METHOD1(OnReceivedLongPollIntervalUpdate, void(const base::TimeDelta&)); | |
41 MOCK_METHOD1(OnReceivedSessionsCommitDelay, void(const base::TimeDelta&)); | |
42 MOCK_METHOD1(OnReceivedClientInvalidationHintBufferSize, void(int)); | |
43 MOCK_METHOD1(OnSyncProtocolError, void(const SyncProtocolError&)); | |
44 }; | |
45 | |
46 // Builds a ClientToServerResponse with some data type ids, including | |
47 // invalid ones. GetTypesToMigrate() should return only the valid | |
48 // model types. | |
49 TEST(SyncerProtoUtil, GetTypesToMigrate) { | |
50 sync_pb::ClientToServerResponse response; | |
51 response.add_migrated_data_type_id( | |
52 GetSpecificsFieldNumberFromModelType(BOOKMARKS)); | |
53 response.add_migrated_data_type_id( | |
54 GetSpecificsFieldNumberFromModelType(HISTORY_DELETE_DIRECTIVES)); | |
55 response.add_migrated_data_type_id(-1); | |
56 EXPECT_EQ(ModelTypeSet(BOOKMARKS, HISTORY_DELETE_DIRECTIVES), | |
57 GetTypesToMigrate(response)); | |
58 } | |
59 | |
60 // Builds a ClientToServerResponse_Error with some error data type | |
61 // ids, including invalid ones. ConvertErrorPBToSyncProtocolError() should | |
62 // return a SyncProtocolError with only the valid model types. | |
63 TEST(SyncerProtoUtil, ConvertErrorPBToSyncProtocolError) { | |
64 sync_pb::ClientToServerResponse_Error error_pb; | |
65 error_pb.set_error_type(sync_pb::SyncEnums::THROTTLED); | |
66 error_pb.add_error_data_type_ids( | |
67 GetSpecificsFieldNumberFromModelType(BOOKMARKS)); | |
68 error_pb.add_error_data_type_ids( | |
69 GetSpecificsFieldNumberFromModelType(HISTORY_DELETE_DIRECTIVES)); | |
70 error_pb.add_error_data_type_ids(-1); | |
71 SyncProtocolError error = ConvertErrorPBToSyncProtocolError(error_pb); | |
72 EXPECT_EQ(ModelTypeSet(BOOKMARKS, HISTORY_DELETE_DIRECTIVES), | |
73 error.error_data_types); | |
74 } | |
75 | |
76 // Tests NameFromSyncEntity and NameFromCommitEntryResponse when only the name | |
77 // field is provided. | |
78 TEST(SyncerProtoUtil, NameExtractionOneName) { | |
79 SyncEntity one_name_entity; | |
80 CommitResponse_EntryResponse one_name_response; | |
81 | |
82 const std::string one_name_string("Eggheadednesses"); | |
83 one_name_entity.set_name(one_name_string); | |
84 one_name_response.set_name(one_name_string); | |
85 | |
86 const std::string name_a = | |
87 SyncerProtoUtil::NameFromSyncEntity(one_name_entity); | |
88 EXPECT_EQ(one_name_string, name_a); | |
89 } | |
90 | |
91 TEST(SyncerProtoUtil, NameExtractionOneUniqueName) { | |
92 SyncEntity one_name_entity; | |
93 CommitResponse_EntryResponse one_name_response; | |
94 | |
95 const std::string one_name_string("Eggheadednesses"); | |
96 | |
97 one_name_entity.set_non_unique_name(one_name_string); | |
98 one_name_response.set_non_unique_name(one_name_string); | |
99 | |
100 const std::string name_a = | |
101 SyncerProtoUtil::NameFromSyncEntity(one_name_entity); | |
102 EXPECT_EQ(one_name_string, name_a); | |
103 } | |
104 | |
105 // Tests NameFromSyncEntity and NameFromCommitEntryResponse when both the name | |
106 // field and the non_unique_name fields are provided. | |
107 // Should prioritize non_unique_name. | |
108 TEST(SyncerProtoUtil, NameExtractionTwoNames) { | |
109 SyncEntity two_name_entity; | |
110 CommitResponse_EntryResponse two_name_response; | |
111 | |
112 const std::string neuro("Neuroanatomists"); | |
113 const std::string oxyphen("Oxyphenbutazone"); | |
114 | |
115 two_name_entity.set_name(oxyphen); | |
116 two_name_entity.set_non_unique_name(neuro); | |
117 | |
118 two_name_response.set_name(oxyphen); | |
119 two_name_response.set_non_unique_name(neuro); | |
120 | |
121 const std::string name_a = | |
122 SyncerProtoUtil::NameFromSyncEntity(two_name_entity); | |
123 EXPECT_EQ(neuro, name_a); | |
124 } | |
125 | |
126 class SyncerProtoUtilTest : public testing::Test { | |
127 public: | |
128 void SetUp() override { dir_maker_.SetUp(); } | |
129 | |
130 void TearDown() override { dir_maker_.TearDown(); } | |
131 | |
132 syncable::Directory* directory() { | |
133 return dir_maker_.directory(); | |
134 } | |
135 | |
136 // Helper function to call GetProtocolErrorFromResponse. Allows not adding | |
137 // individual tests as friends to SyncerProtoUtil. | |
138 static SyncProtocolError CallGetProtocolErrorFromResponse( | |
139 const sync_pb::ClientToServerResponse& response, | |
140 syncable::Directory* directory) { | |
141 return SyncerProtoUtil::GetProtocolErrorFromResponse(response, directory); | |
142 } | |
143 | |
144 protected: | |
145 base::MessageLoop message_loop_; | |
146 TestDirectorySetterUpper dir_maker_; | |
147 }; | |
148 | |
149 TEST_F(SyncerProtoUtilTest, VerifyResponseBirthday) { | |
150 // Both sides empty | |
151 EXPECT_TRUE(directory()->store_birthday().empty()); | |
152 sync_pb::ClientToServerResponse response; | |
153 SyncProtocolError sync_protocol_error; | |
154 response.set_error_code(sync_pb::SyncEnums::SUCCESS); | |
155 | |
156 sync_protocol_error = CallGetProtocolErrorFromResponse(response, directory()); | |
157 EXPECT_EQ(NOT_MY_BIRTHDAY, sync_protocol_error.error_type); | |
158 EXPECT_EQ(DISABLE_SYNC_ON_CLIENT, sync_protocol_error.action); | |
159 | |
160 // Remote set, local empty | |
161 response.set_store_birthday("flan"); | |
162 sync_protocol_error = CallGetProtocolErrorFromResponse(response, directory()); | |
163 EXPECT_EQ(SYNC_SUCCESS, sync_protocol_error.error_type); | |
164 EXPECT_EQ(UNKNOWN_ACTION, sync_protocol_error.action); | |
165 EXPECT_EQ(directory()->store_birthday(), "flan"); | |
166 | |
167 // Remote empty, local set. | |
168 response.clear_store_birthday(); | |
169 sync_protocol_error = CallGetProtocolErrorFromResponse(response, directory()); | |
170 EXPECT_EQ(SYNC_SUCCESS, sync_protocol_error.error_type); | |
171 EXPECT_EQ(UNKNOWN_ACTION, sync_protocol_error.action); | |
172 EXPECT_EQ(directory()->store_birthday(), "flan"); | |
173 | |
174 // Doesn't match | |
175 response.set_store_birthday("meat"); | |
176 response.set_error_code(sync_pb::SyncEnums::NOT_MY_BIRTHDAY); | |
177 sync_protocol_error = CallGetProtocolErrorFromResponse(response, directory()); | |
178 EXPECT_EQ(NOT_MY_BIRTHDAY, sync_protocol_error.error_type); | |
179 EXPECT_EQ(DISABLE_SYNC_ON_CLIENT, sync_protocol_error.action); | |
180 | |
181 // Doesn't match. CLIENT_DATA_OBSOLETE error is set. | |
182 response.set_error_code(sync_pb::SyncEnums::CLIENT_DATA_OBSOLETE); | |
183 sync_protocol_error = CallGetProtocolErrorFromResponse(response, directory()); | |
184 EXPECT_EQ(CLIENT_DATA_OBSOLETE, sync_protocol_error.error_type); | |
185 EXPECT_EQ(RESET_LOCAL_SYNC_DATA, sync_protocol_error.action); | |
186 } | |
187 | |
188 TEST_F(SyncerProtoUtilTest, VerifyDisabledByAdmin) { | |
189 // No error code | |
190 sync_pb::ClientToServerResponse response; | |
191 SyncProtocolError sync_protocol_error; | |
192 directory()->set_store_birthday("flan"); | |
193 response.set_error_code(sync_pb::SyncEnums::SUCCESS); | |
194 | |
195 sync_protocol_error = CallGetProtocolErrorFromResponse(response, directory()); | |
196 EXPECT_EQ(SYNC_SUCCESS, sync_protocol_error.error_type); | |
197 EXPECT_EQ(UNKNOWN_ACTION, sync_protocol_error.action); | |
198 | |
199 // Has error code, but not disabled | |
200 response.set_error_code(sync_pb::SyncEnums::NOT_MY_BIRTHDAY); | |
201 sync_protocol_error = CallGetProtocolErrorFromResponse(response, directory()); | |
202 EXPECT_EQ(NOT_MY_BIRTHDAY, sync_protocol_error.error_type); | |
203 EXPECT_NE(UNKNOWN_ACTION, sync_protocol_error.action); | |
204 | |
205 // Has error code, and is disabled by admin | |
206 response.set_error_code(sync_pb::SyncEnums::DISABLED_BY_ADMIN); | |
207 sync_protocol_error = CallGetProtocolErrorFromResponse(response, directory()); | |
208 EXPECT_EQ(DISABLED_BY_ADMIN, sync_protocol_error.error_type); | |
209 EXPECT_EQ(STOP_SYNC_FOR_DISABLED_ACCOUNT, sync_protocol_error.action); | |
210 } | |
211 | |
212 TEST_F(SyncerProtoUtilTest, AddRequestBirthday) { | |
213 EXPECT_TRUE(directory()->store_birthday().empty()); | |
214 ClientToServerMessage msg; | |
215 SyncerProtoUtil::AddRequestBirthday(directory(), &msg); | |
216 EXPECT_FALSE(msg.has_store_birthday()); | |
217 | |
218 directory()->set_store_birthday("meat"); | |
219 SyncerProtoUtil::AddRequestBirthday(directory(), &msg); | |
220 EXPECT_EQ(msg.store_birthday(), "meat"); | |
221 } | |
222 | |
223 class DummyConnectionManager : public ServerConnectionManager { | |
224 public: | |
225 explicit DummyConnectionManager(CancelationSignal* signal) | |
226 : ServerConnectionManager("unused", 0, false, signal), | |
227 send_error_(false) {} | |
228 | |
229 ~DummyConnectionManager() override {} | |
230 bool PostBufferWithCachedAuth(PostBufferParams* params) override { | |
231 if (send_error_) { | |
232 return false; | |
233 } | |
234 | |
235 sync_pb::ClientToServerResponse response; | |
236 response.SerializeToString(¶ms->buffer_out); | |
237 | |
238 return true; | |
239 } | |
240 | |
241 void set_send_error(bool send) { | |
242 send_error_ = send; | |
243 } | |
244 | |
245 private: | |
246 bool send_error_; | |
247 }; | |
248 | |
249 TEST_F(SyncerProtoUtilTest, PostAndProcessHeaders) { | |
250 CancelationSignal signal; | |
251 DummyConnectionManager dcm(&signal); | |
252 ClientToServerMessage msg; | |
253 SyncerProtoUtil::SetProtocolVersion(&msg); | |
254 msg.set_share("required"); | |
255 msg.set_message_contents(ClientToServerMessage::GET_UPDATES); | |
256 sync_pb::ClientToServerResponse response; | |
257 | |
258 dcm.set_send_error(true); | |
259 EXPECT_FALSE(SyncerProtoUtil::PostAndProcessHeaders(&dcm, NULL, | |
260 msg, &response)); | |
261 | |
262 dcm.set_send_error(false); | |
263 EXPECT_TRUE(SyncerProtoUtil::PostAndProcessHeaders(&dcm, NULL, | |
264 msg, &response)); | |
265 } | |
266 | |
267 } // namespace syncer | |
OLD | NEW |