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 // Keep this file in sync with the .proto files in this directory. | |
6 | |
7 #include "sync/protocol/proto_value_conversions.h" | |
8 | |
9 #include <memory> | |
10 #include <string> | |
11 | |
12 #include "base/strings/string_number_conversions.h" | |
13 #include "base/time/time.h" | |
14 #include "base/values.h" | |
15 #include "sync/internal_api/public/base/model_type.h" | |
16 #include "sync/protocol/app_notification_specifics.pb.h" | |
17 #include "sync/protocol/app_setting_specifics.pb.h" | |
18 #include "sync/protocol/app_specifics.pb.h" | |
19 #include "sync/protocol/autofill_specifics.pb.h" | |
20 #include "sync/protocol/bookmark_specifics.pb.h" | |
21 #include "sync/protocol/device_info_specifics.pb.h" | |
22 #include "sync/protocol/encryption.pb.h" | |
23 #include "sync/protocol/experiments_specifics.pb.h" | |
24 #include "sync/protocol/extension_setting_specifics.pb.h" | |
25 #include "sync/protocol/extension_specifics.pb.h" | |
26 #include "sync/protocol/favicon_image_specifics.pb.h" | |
27 #include "sync/protocol/favicon_tracking_specifics.pb.h" | |
28 #include "sync/protocol/managed_user_setting_specifics.pb.h" | |
29 #include "sync/protocol/managed_user_shared_setting_specifics.pb.h" | |
30 #include "sync/protocol/managed_user_specifics.pb.h" | |
31 #include "sync/protocol/managed_user_whitelist_specifics.pb.h" | |
32 #include "sync/protocol/nigori_specifics.pb.h" | |
33 #include "sync/protocol/password_specifics.pb.h" | |
34 #include "sync/protocol/preference_specifics.pb.h" | |
35 #include "sync/protocol/priority_preference_specifics.pb.h" | |
36 #include "sync/protocol/search_engine_specifics.pb.h" | |
37 #include "sync/protocol/session_specifics.pb.h" | |
38 #include "sync/protocol/sync.pb.h" | |
39 #include "sync/protocol/theme_specifics.pb.h" | |
40 #include "sync/protocol/typed_url_specifics.pb.h" | |
41 #include "sync/protocol/wifi_credential_specifics.pb.h" | |
42 #include "testing/gtest/include/gtest/gtest.h" | |
43 | |
44 namespace syncer { | |
45 namespace { | |
46 | |
47 class ProtoValueConversionsTest : public testing::Test { | |
48 protected: | |
49 template <class T> | |
50 void TestSpecificsToValue( | |
51 std::unique_ptr<base::DictionaryValue> (*specifics_to_value)(const T&)) { | |
52 const T& specifics(T::default_instance()); | |
53 std::unique_ptr<base::DictionaryValue> value = | |
54 specifics_to_value(specifics); | |
55 // We can't do much but make sure that this doesn't crash. | |
56 } | |
57 }; | |
58 | |
59 TEST_F(ProtoValueConversionsTest, ProtoChangeCheck) { | |
60 // If this number changes, that means we added or removed a data | |
61 // type. Don't forget to add a unit test for {New | |
62 // type}SpecificsToValue below. | |
63 EXPECT_EQ(37, MODEL_TYPE_COUNT); | |
64 | |
65 // We'd also like to check if we changed any field in our messages. | |
66 // However, that's hard to do: sizeof could work, but it's | |
67 // platform-dependent. default_instance().ByteSize() won't change | |
68 // for most changes, since most of our fields are optional. So we | |
69 // just settle for comments in the proto files. | |
70 } | |
71 | |
72 TEST_F(ProtoValueConversionsTest, EncryptedDataToValue) { | |
73 TestSpecificsToValue(EncryptedDataToValue); | |
74 } | |
75 | |
76 TEST_F(ProtoValueConversionsTest, SessionHeaderToValue) { | |
77 TestSpecificsToValue(SessionHeaderToValue); | |
78 } | |
79 | |
80 TEST_F(ProtoValueConversionsTest, SessionTabToValue) { | |
81 TestSpecificsToValue(SessionTabToValue); | |
82 } | |
83 | |
84 TEST_F(ProtoValueConversionsTest, SessionWindowToValue) { | |
85 TestSpecificsToValue(SessionWindowToValue); | |
86 } | |
87 | |
88 TEST_F(ProtoValueConversionsTest, TabNavigationToValue) { | |
89 TestSpecificsToValue(TabNavigationToValue); | |
90 } | |
91 | |
92 TEST_F(ProtoValueConversionsTest, NavigationRedirectToValue) { | |
93 TestSpecificsToValue(NavigationRedirectToValue); | |
94 } | |
95 | |
96 TEST_F(ProtoValueConversionsTest, PasswordSpecificsData) { | |
97 sync_pb::PasswordSpecificsData specifics; | |
98 specifics.set_password_value("secret"); | |
99 std::unique_ptr<base::DictionaryValue> value( | |
100 PasswordSpecificsDataToValue(specifics)); | |
101 EXPECT_FALSE(value->empty()); | |
102 std::string password_value; | |
103 EXPECT_TRUE(value->GetString("password_value", &password_value)); | |
104 EXPECT_EQ("<redacted>", password_value); | |
105 } | |
106 | |
107 TEST_F(ProtoValueConversionsTest, AppListSpecificsToValue) { | |
108 TestSpecificsToValue(AppListSpecificsToValue); | |
109 } | |
110 | |
111 TEST_F(ProtoValueConversionsTest, AppNotificationToValue) { | |
112 TestSpecificsToValue(AppNotificationToValue); | |
113 } | |
114 | |
115 TEST_F(ProtoValueConversionsTest, AppSettingSpecificsToValue) { | |
116 sync_pb::AppNotificationSettings specifics; | |
117 specifics.set_disabled(true); | |
118 specifics.set_oauth_client_id("some_id_value"); | |
119 std::unique_ptr<base::DictionaryValue> value(AppSettingsToValue(specifics)); | |
120 EXPECT_FALSE(value->empty()); | |
121 bool disabled_value = false; | |
122 std::string oauth_client_id_value; | |
123 EXPECT_TRUE(value->GetBoolean("disabled", &disabled_value)); | |
124 EXPECT_EQ(true, disabled_value); | |
125 EXPECT_TRUE(value->GetString("oauth_client_id", &oauth_client_id_value)); | |
126 EXPECT_EQ("some_id_value", oauth_client_id_value); | |
127 } | |
128 | |
129 TEST_F(ProtoValueConversionsTest, AppSpecificsToValue) { | |
130 TestSpecificsToValue(AppSpecificsToValue); | |
131 } | |
132 | |
133 TEST_F(ProtoValueConversionsTest, ArcPackageSpecificsToValue) { | |
134 TestSpecificsToValue(ArcPackageSpecificsToValue); | |
135 } | |
136 | |
137 TEST_F(ProtoValueConversionsTest, AutofillSpecificsToValue) { | |
138 TestSpecificsToValue(AutofillSpecificsToValue); | |
139 } | |
140 | |
141 TEST_F(ProtoValueConversionsTest, AutofillProfileSpecificsToValue) { | |
142 TestSpecificsToValue(AutofillProfileSpecificsToValue); | |
143 } | |
144 | |
145 TEST_F(ProtoValueConversionsTest, AutofillWalletSpecificsToValue) { | |
146 TestSpecificsToValue(AutofillWalletSpecificsToValue); | |
147 } | |
148 | |
149 TEST_F(ProtoValueConversionsTest, WalletMetadataSpecificsToValue) { | |
150 TestSpecificsToValue(WalletMetadataSpecificsToValue); | |
151 } | |
152 | |
153 TEST_F(ProtoValueConversionsTest, BookmarkSpecificsToValue) { | |
154 TestSpecificsToValue(BookmarkSpecificsToValue); | |
155 } | |
156 | |
157 TEST_F(ProtoValueConversionsTest, BookmarkSpecificsData) { | |
158 const base::Time creation_time(base::Time::Now()); | |
159 const std::string icon_url = "http://www.google.com/favicon.ico"; | |
160 sync_pb::BookmarkSpecifics specifics; | |
161 specifics.set_creation_time_us(creation_time.ToInternalValue()); | |
162 specifics.set_icon_url(icon_url); | |
163 sync_pb::MetaInfo* meta_1 = specifics.add_meta_info(); | |
164 meta_1->set_key("key1"); | |
165 meta_1->set_value("value1"); | |
166 sync_pb::MetaInfo* meta_2 = specifics.add_meta_info(); | |
167 meta_2->set_key("key2"); | |
168 meta_2->set_value("value2"); | |
169 | |
170 std::unique_ptr<base::DictionaryValue> value( | |
171 BookmarkSpecificsToValue(specifics)); | |
172 EXPECT_FALSE(value->empty()); | |
173 std::string encoded_time; | |
174 EXPECT_TRUE(value->GetString("creation_time_us", &encoded_time)); | |
175 EXPECT_EQ(base::Int64ToString(creation_time.ToInternalValue()), encoded_time); | |
176 std::string encoded_icon_url; | |
177 EXPECT_TRUE(value->GetString("icon_url", &encoded_icon_url)); | |
178 EXPECT_EQ(icon_url, encoded_icon_url); | |
179 base::ListValue* meta_info_list; | |
180 ASSERT_TRUE(value->GetList("meta_info", &meta_info_list)); | |
181 EXPECT_EQ(2u, meta_info_list->GetSize()); | |
182 base::DictionaryValue* meta_info; | |
183 std::string meta_key; | |
184 std::string meta_value; | |
185 ASSERT_TRUE(meta_info_list->GetDictionary(0, &meta_info)); | |
186 EXPECT_TRUE(meta_info->GetString("key", &meta_key)); | |
187 EXPECT_TRUE(meta_info->GetString("value", &meta_value)); | |
188 EXPECT_EQ("key1", meta_key); | |
189 EXPECT_EQ("value1", meta_value); | |
190 ASSERT_TRUE(meta_info_list->GetDictionary(1, &meta_info)); | |
191 EXPECT_TRUE(meta_info->GetString("key", &meta_key)); | |
192 EXPECT_TRUE(meta_info->GetString("value", &meta_value)); | |
193 EXPECT_EQ("key2", meta_key); | |
194 EXPECT_EQ("value2", meta_value); | |
195 } | |
196 | |
197 TEST_F(ProtoValueConversionsTest, LinkedAppIconInfoToValue) { | |
198 TestSpecificsToValue(LinkedAppIconInfoToValue); | |
199 } | |
200 | |
201 TEST_F(ProtoValueConversionsTest, PriorityPreferenceSpecificsToValue) { | |
202 TestSpecificsToValue(PriorityPreferenceSpecificsToValue); | |
203 } | |
204 | |
205 TEST_F(ProtoValueConversionsTest, DeviceInfoSpecificsToValue) { | |
206 TestSpecificsToValue(DeviceInfoSpecificsToValue); | |
207 } | |
208 | |
209 TEST_F(ProtoValueConversionsTest, ExperimentsSpecificsToValue) { | |
210 TestSpecificsToValue(ExperimentsSpecificsToValue); | |
211 } | |
212 | |
213 TEST_F(ProtoValueConversionsTest, ExtensionSettingSpecificsToValue) { | |
214 TestSpecificsToValue(ExtensionSettingSpecificsToValue); | |
215 } | |
216 | |
217 TEST_F(ProtoValueConversionsTest, ExtensionSpecificsToValue) { | |
218 TestSpecificsToValue(ExtensionSpecificsToValue); | |
219 } | |
220 | |
221 TEST_F(ProtoValueConversionsTest, FaviconImageSpecificsToValue) { | |
222 TestSpecificsToValue(FaviconImageSpecificsToValue); | |
223 } | |
224 | |
225 TEST_F(ProtoValueConversionsTest, FaviconTrackingSpecificsToValue) { | |
226 TestSpecificsToValue(FaviconTrackingSpecificsToValue); | |
227 } | |
228 | |
229 TEST_F(ProtoValueConversionsTest, HistoryDeleteDirectiveSpecificsToValue) { | |
230 TestSpecificsToValue(HistoryDeleteDirectiveSpecificsToValue); | |
231 } | |
232 | |
233 TEST_F(ProtoValueConversionsTest, ManagedUserSettingSpecificsToValue) { | |
234 TestSpecificsToValue(ManagedUserSettingSpecificsToValue); | |
235 } | |
236 | |
237 TEST_F(ProtoValueConversionsTest, ManagedUserSpecificsToValue) { | |
238 TestSpecificsToValue(ManagedUserSpecificsToValue); | |
239 } | |
240 | |
241 TEST_F(ProtoValueConversionsTest, ManagedUserSharedSettingSpecificsToValue) { | |
242 TestSpecificsToValue(ManagedUserSharedSettingSpecificsToValue); | |
243 } | |
244 | |
245 TEST_F(ProtoValueConversionsTest, ManagedUserWhitelistSpecificsToValue) { | |
246 TestSpecificsToValue(ManagedUserWhitelistSpecificsToValue); | |
247 } | |
248 | |
249 TEST_F(ProtoValueConversionsTest, NigoriSpecificsToValue) { | |
250 TestSpecificsToValue(NigoriSpecificsToValue); | |
251 } | |
252 | |
253 TEST_F(ProtoValueConversionsTest, PasswordSpecificsToValue) { | |
254 TestSpecificsToValue(PasswordSpecificsToValue); | |
255 } | |
256 | |
257 TEST_F(ProtoValueConversionsTest, PreferenceSpecificsToValue) { | |
258 TestSpecificsToValue(PreferenceSpecificsToValue); | |
259 } | |
260 | |
261 TEST_F(ProtoValueConversionsTest, SearchEngineSpecificsToValue) { | |
262 TestSpecificsToValue(SearchEngineSpecificsToValue); | |
263 } | |
264 | |
265 TEST_F(ProtoValueConversionsTest, SessionSpecificsToValue) { | |
266 TestSpecificsToValue(SessionSpecificsToValue); | |
267 } | |
268 | |
269 TEST_F(ProtoValueConversionsTest, SyncedNotificationAppInfoSpecificsToValue) { | |
270 TestSpecificsToValue(SyncedNotificationAppInfoSpecificsToValue); | |
271 } | |
272 | |
273 TEST_F(ProtoValueConversionsTest, SyncedNotificationSpecificsToValue) { | |
274 TestSpecificsToValue(SyncedNotificationSpecificsToValue); | |
275 } | |
276 | |
277 TEST_F(ProtoValueConversionsTest, ThemeSpecificsToValue) { | |
278 TestSpecificsToValue(ThemeSpecificsToValue); | |
279 } | |
280 | |
281 TEST_F(ProtoValueConversionsTest, TypedUrlSpecificsToValue) { | |
282 TestSpecificsToValue(TypedUrlSpecificsToValue); | |
283 } | |
284 | |
285 TEST_F(ProtoValueConversionsTest, DictionarySpecificsToValue) { | |
286 TestSpecificsToValue(DictionarySpecificsToValue); | |
287 } | |
288 | |
289 TEST_F(ProtoValueConversionsTest, ArticleSpecificsToValue) { | |
290 TestSpecificsToValue(ArticleSpecificsToValue); | |
291 } | |
292 | |
293 TEST_F(ProtoValueConversionsTest, WifiCredentialSpecificsToValue) { | |
294 TestSpecificsToValue(WifiCredentialSpecificsToValue); | |
295 } | |
296 | |
297 // TODO(akalin): Figure out how to better test EntitySpecificsToValue. | |
298 | |
299 TEST_F(ProtoValueConversionsTest, EntitySpecificsToValue) { | |
300 sync_pb::EntitySpecifics specifics; | |
301 // Touch the extensions to make sure it shows up in the generated | |
302 // value. | |
303 #define SET_FIELD(key) (void)specifics.mutable_##key() | |
304 | |
305 SET_FIELD(app); | |
306 SET_FIELD(app_list); | |
307 SET_FIELD(app_notification); | |
308 SET_FIELD(app_setting); | |
309 SET_FIELD(arc_package); | |
310 SET_FIELD(article); | |
311 SET_FIELD(autofill); | |
312 SET_FIELD(autofill_profile); | |
313 SET_FIELD(bookmark); | |
314 SET_FIELD(device_info); | |
315 SET_FIELD(dictionary); | |
316 SET_FIELD(experiments); | |
317 SET_FIELD(extension); | |
318 SET_FIELD(extension_setting); | |
319 SET_FIELD(favicon_image); | |
320 SET_FIELD(favicon_tracking); | |
321 SET_FIELD(history_delete_directive); | |
322 SET_FIELD(managed_user_setting); | |
323 SET_FIELD(managed_user_shared_setting); | |
324 SET_FIELD(managed_user_whitelist); | |
325 SET_FIELD(managed_user); | |
326 SET_FIELD(nigori); | |
327 SET_FIELD(password); | |
328 SET_FIELD(preference); | |
329 SET_FIELD(priority_preference); | |
330 SET_FIELD(search_engine); | |
331 SET_FIELD(session); | |
332 SET_FIELD(synced_notification); | |
333 SET_FIELD(synced_notification_app_info); | |
334 SET_FIELD(theme); | |
335 SET_FIELD(typed_url); | |
336 SET_FIELD(wifi_credential); | |
337 SET_FIELD(autofill_wallet); | |
338 SET_FIELD(wallet_metadata); | |
339 | |
340 #undef SET_FIELD | |
341 | |
342 std::unique_ptr<base::DictionaryValue> value( | |
343 EntitySpecificsToValue(specifics)); | |
344 EXPECT_EQ(MODEL_TYPE_COUNT - FIRST_REAL_MODEL_TYPE - | |
345 (LAST_PROXY_TYPE - FIRST_PROXY_TYPE + 1), | |
346 static_cast<int>(value->size())); | |
347 } | |
348 | |
349 namespace { | |
350 // Returns whether the given value has specifics under the entries in the given | |
351 // path. | |
352 bool ValueHasSpecifics(const base::DictionaryValue& value, | |
353 const std::string& path) { | |
354 const base::ListValue* entities_list = NULL; | |
355 const base::DictionaryValue* entry_dictionary = NULL; | |
356 const base::DictionaryValue* specifics_dictionary = NULL; | |
357 | |
358 if (!value.GetList(path, &entities_list)) | |
359 return false; | |
360 | |
361 if (!entities_list->GetDictionary(0, &entry_dictionary)) | |
362 return false; | |
363 | |
364 return entry_dictionary->GetDictionary("specifics", | |
365 &specifics_dictionary); | |
366 } | |
367 } // namespace | |
368 | |
369 // Create a ClientToServerMessage with an EntitySpecifics. Converting it to | |
370 // a value should respect the |include_specifics| flag. | |
371 TEST_F(ProtoValueConversionsTest, ClientToServerMessageToValue) { | |
372 sync_pb::ClientToServerMessage message; | |
373 sync_pb::CommitMessage* commit_message = message.mutable_commit(); | |
374 sync_pb::SyncEntity* entity = commit_message->add_entries(); | |
375 entity->mutable_specifics(); | |
376 | |
377 std::unique_ptr<base::DictionaryValue> value_with_specifics( | |
378 ClientToServerMessageToValue(message, true /* include_specifics */)); | |
379 EXPECT_FALSE(value_with_specifics->empty()); | |
380 EXPECT_TRUE(ValueHasSpecifics(*(value_with_specifics.get()), | |
381 "commit.entries")); | |
382 | |
383 std::unique_ptr<base::DictionaryValue> value_without_specifics( | |
384 ClientToServerMessageToValue(message, false /* include_specifics */)); | |
385 EXPECT_FALSE(value_without_specifics->empty()); | |
386 EXPECT_FALSE(ValueHasSpecifics(*(value_without_specifics.get()), | |
387 "commit.entries")); | |
388 } | |
389 | |
390 // Create a ClientToServerResponse with an EntitySpecifics. Converting it to | |
391 // a value should respect the |include_specifics| flag. | |
392 TEST_F(ProtoValueConversionsTest, ClientToServerResponseToValue) { | |
393 sync_pb::ClientToServerResponse message; | |
394 sync_pb::GetUpdatesResponse* response = message.mutable_get_updates(); | |
395 sync_pb::SyncEntity* entity = response->add_entries(); | |
396 entity->mutable_specifics(); | |
397 | |
398 std::unique_ptr<base::DictionaryValue> value_with_specifics( | |
399 ClientToServerResponseToValue(message, true /* include_specifics */)); | |
400 EXPECT_FALSE(value_with_specifics->empty()); | |
401 EXPECT_TRUE(ValueHasSpecifics(*(value_with_specifics.get()), | |
402 "get_updates.entries")); | |
403 | |
404 std::unique_ptr<base::DictionaryValue> value_without_specifics( | |
405 ClientToServerResponseToValue(message, false /* include_specifics */)); | |
406 EXPECT_FALSE(value_without_specifics->empty()); | |
407 EXPECT_FALSE(ValueHasSpecifics(*(value_without_specifics.get()), | |
408 "get_updates.entries")); | |
409 } | |
410 | |
411 TEST_F(ProtoValueConversionsTest, AttachmentIdProtoToValue) { | |
412 TestSpecificsToValue(AttachmentIdProtoToValue); | |
413 } | |
414 | |
415 } // namespace | |
416 } // namespace syncer | |
OLD | NEW |