|
OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2011 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 "base/memory/scoped_ptr.h" | |
6 #include "base/string_util.h" | |
7 #include "base/time.h" | |
8 #include "base/utf_string_conversions.h" | |
9 #include "chrome/browser/search_engines/template_url.h" | |
10 #include "chrome/browser/search_engines/template_url_service.h" | |
11 #include "chrome/browser/sync/protocol/search_engine_specifics.pb.h" | |
12 #include "chrome/test/base/testing_profile.h" | |
13 #include "chrome/test/base/testing_browser_process_test.h" | |
Nicolas Zea
2011/08/15 23:40:00
last include is out of abc order
SteveT
2011/08/16 00:08:59
Done.
| |
14 | |
15 using base::Time; | |
16 | |
17 namespace { | |
Nicolas Zea
2011/08/15 23:40:00
nit: blank line after (and before close brace)
SteveT
2011/08/16 00:08:59
Done.
| |
18 // Extract the GUID from a search engine SyncData. | |
19 std::string GetGUID(const SyncData& sync_data) { | |
20 return sync_data.GetSpecifics().GetExtension( | |
21 sync_pb::search_engine).sync_guid(); | |
22 } | |
23 | |
24 // Extract the keyword from a search engine SyncData. | |
25 std::string GetURL(const SyncData& sync_data) { | |
26 return sync_data.GetSpecifics().GetExtension( | |
27 sync_pb::search_engine).url(); | |
28 } | |
29 | |
30 // Extract the keyword from a search engine SyncData. | |
31 std::string GetKeyword(const SyncData& sync_data) { | |
32 return sync_data.GetSpecifics().GetExtension( | |
33 sync_pb::search_engine).keyword(); | |
34 } | |
35 } | |
Nicolas Zea
2011/08/15 23:40:00
nit: extend the namespace to be the entire file an
SteveT
2011/08/16 00:08:59
Done.
| |
36 | |
37 // Dummy SyncChangeProcessor used to help review what SyncChanges are pushed | |
38 // back up to Sync. | |
39 class TestChangeProcessor : public SyncChangeProcessor { | |
40 public: | |
41 TestChangeProcessor() : erroneous_(false) { | |
42 } | |
43 virtual ~TestChangeProcessor() { } | |
44 | |
45 // Store a copy of all the changes passed in so we can examine them later. | |
46 virtual SyncError ProcessSyncChanges( | |
47 const tracked_objects::Location& from_here, | |
48 const SyncChangeList& change_list) { | |
49 if (erroneous_) | |
50 return SyncError(FROM_HERE, "Some error.", syncable::SEARCH_ENGINES); | |
51 | |
52 change_map_.erase(change_map_.begin(), change_map_.end()); | |
53 for (SyncChangeList::const_iterator iter = change_list.begin(); | |
54 iter != change_list.end(); ++iter) { | |
55 change_map_[GetGUID(iter->sync_data())] = *iter; | |
56 } | |
57 | |
58 return SyncError(); | |
59 } | |
60 | |
61 bool ContainsGUID(const std::string& guid) { | |
62 return change_map_.find(guid) != change_map_.end(); | |
63 } | |
64 | |
65 SyncChange GetChangeByGUID(const std::string& guid) { | |
66 DCHECK(ContainsGUID(guid)); | |
67 return change_map_[guid]; | |
68 } | |
69 | |
70 int change_list_size() { return change_map_.size(); } | |
71 | |
72 void set_erroneous(bool erroneous) { erroneous_ = erroneous; } | |
73 | |
74 private: | |
75 // Track the changes received in ProcessSyncChanges. | |
76 std::map<std::string, SyncChange> change_map_; | |
77 bool erroneous_; | |
78 | |
79 DISALLOW_COPY_AND_ASSIGN(TestChangeProcessor); | |
80 }; | |
81 | |
82 class TemplateURLServiceSyncTest : public TestingBrowserProcessTest { | |
83 public: | |
84 typedef TemplateURLService::SyncDataMap SyncDataMap; | |
85 | |
86 TemplateURLServiceSyncTest() {} | |
87 | |
88 virtual void SetUp() { | |
89 profile_a_.reset(new TestingProfile); | |
90 model_a_.reset(new TemplateURLService(profile_a_.get())); | |
91 model_a_->Load(); | |
92 profile_b_.reset(new TestingProfile); | |
93 model_b_.reset(new TemplateURLService(profile_b_.get())); | |
94 model_b_->Load(); | |
95 } | |
96 | |
97 virtual void TearDown() { } | |
98 | |
99 TemplateURLService* model() { return model_a_.get(); } | |
100 // For readability, we redefine an accessor for Model A for use in tests that | |
101 // involve syncing two models. | |
102 TemplateURLService* model_a() { return model_a_.get(); } | |
103 TemplateURLService* model_b() { return model_b_.get(); } | |
104 TestChangeProcessor* processor() { return &processor_; } | |
105 | |
106 // Create a TemplateURL with some test values. The caller owns the returned | |
107 // TemplateURL*. | |
108 TemplateURL* CreateTestTemplateURL() const { | |
109 TemplateURL* turl = new TemplateURL(); | |
110 turl->SetURL("http://www.unittest.com/", 0, 0); | |
111 turl->set_keyword(ASCIIToUTF16("unittest")); | |
112 turl->set_short_name(ASCIIToUTF16("unittest")); | |
113 turl->set_safe_for_autoreplace(true); | |
114 GURL favicon_url("http://favicon.url"); | |
115 turl->SetFaviconURL(favicon_url); | |
116 turl->set_date_created(Time::FromTimeT(100)); | |
117 turl->set_last_modified(Time::FromTimeT(100)); | |
118 turl->SetPrepopulateId(999999); | |
119 return turl; | |
120 } | |
121 | |
122 // Convenience helpers for creating TemplateURLs with specific fields. | |
123 TemplateURL* CreateTestTemplateURL(std::string keyword, | |
124 std::string url) const { | |
125 TemplateURL* turl = CreateTestTemplateURL(); | |
126 turl->set_keyword(UTF8ToUTF16(keyword)); | |
127 turl->SetURL(url, 0, 0); | |
128 return turl; | |
129 } | |
130 | |
131 TemplateURL* CreateTestTemplateURL(std::string keyword, | |
132 std::string url, | |
133 std::string guid) const { | |
134 TemplateURL* turl = CreateTestTemplateURL(keyword, url); | |
135 if (!guid.empty()) | |
136 turl->set_sync_guid(guid); | |
137 return turl; | |
138 } | |
139 | |
140 TemplateURL* CreateTestTemplateURL(std::string keyword, | |
141 std::string url, | |
142 std::string guid, | |
143 time_t last_mod) const { | |
144 TemplateURL* turl = CreateTestTemplateURL(keyword, url, guid); | |
145 turl->set_last_modified(Time::FromTimeT(last_mod)); | |
146 return turl; | |
147 } | |
148 | |
149 // Verifies the two TemplateURLs are equal. | |
150 // TODO(stevet): Share this with TemplateURLServiceTest. | |
151 void AssertEquals(const TemplateURL& expected, | |
152 const TemplateURL& actual) const { | |
153 ASSERT_TRUE(TemplateURLRef::SameUrlRefs(expected.url(), actual.url())); | |
154 ASSERT_TRUE(TemplateURLRef::SameUrlRefs(expected.suggestions_url(), | |
155 actual.suggestions_url())); | |
156 ASSERT_EQ(expected.keyword(), actual.keyword()); | |
157 ASSERT_EQ(expected.short_name(), actual.short_name()); | |
158 ASSERT_EQ(JoinString(expected.input_encodings(), ';'), | |
159 JoinString(actual.input_encodings(), ';')); | |
160 ASSERT_TRUE(expected.GetFaviconURL() == actual.GetFaviconURL()); | |
161 ASSERT_EQ(expected.id(), actual.id()); | |
162 ASSERT_EQ(expected.safe_for_autoreplace(), actual.safe_for_autoreplace()); | |
163 ASSERT_EQ(expected.show_in_default_list(), actual.show_in_default_list()); | |
164 ASSERT_TRUE(expected.date_created() == actual.date_created()); | |
165 ASSERT_TRUE(expected.last_modified() == actual.last_modified()); | |
166 } | |
167 | |
168 // Expect that two SyncDataLists have equal contents, in terms of the | |
169 // sync_guid, keyword, and url fields. | |
170 void AssertEquals(const SyncDataList& data1, | |
171 const SyncDataList& data2) const { | |
172 SyncDataMap map1 = TemplateURLService::CreateGUIDToSyncDataMap(data1); | |
173 SyncDataMap map2 = TemplateURLService::CreateGUIDToSyncDataMap(data2); | |
174 | |
175 for (SyncDataMap::const_iterator iter1 = map1.begin(); | |
176 iter1 != map1.end(); iter1++) { | |
177 SyncDataMap::iterator iter2 = map2.find(iter1->first); | |
178 if (iter2 != map2.end()) { | |
179 ASSERT_EQ(GetKeyword(iter1->second), GetKeyword(iter2->second)); | |
180 ASSERT_EQ(GetURL(iter1->second), GetURL(iter2->second)); | |
181 map2.erase(iter2); | |
182 } | |
183 } | |
184 EXPECT_EQ(0U, map2.size()); | |
185 } | |
186 | |
187 // Convenience helper for creating SyncChanges. | |
188 SyncChange CreateTestSyncChange(SyncChange::SyncChangeType type, | |
189 TemplateURL* turl) const { | |
190 return SyncChange(type, | |
191 TemplateURLService::CreateSyncDataFromTemplateURL(*turl)); | |
192 } | |
193 | |
194 // Helper that creates some initial sync data. We cheat a little by specifying | |
195 // GUIDs for easy identification later. We also make the last_modified times | |
196 // slightly older than CreateTestTemplateURL's default, to test conflict | |
197 // resolution. | |
198 SyncDataList CreateInitialSyncData() const { | |
199 SyncDataList list; | |
200 | |
201 scoped_ptr<TemplateURL> turl( | |
202 CreateTestTemplateURL("key1", "http://key1.com", "key1", 90)); | |
203 list.push_back(TemplateURLService::CreateSyncDataFromTemplateURL(*turl)); | |
204 turl.reset(CreateTestTemplateURL("key2", "http://key2.com", "key2", 90)); | |
205 list.push_back(TemplateURLService::CreateSyncDataFromTemplateURL(*turl)); | |
206 turl.reset(CreateTestTemplateURL("key3", "http://key3.com", "key3", 90)); | |
207 list.push_back(TemplateURLService::CreateSyncDataFromTemplateURL(*turl)); | |
208 | |
209 return list; | |
210 } | |
211 | |
212 protected: | |
213 // We keep two TemplateURLServices to test syncing between them. | |
214 scoped_ptr<TestingProfile> profile_a_; | |
215 scoped_ptr<TemplateURLService> model_a_; | |
216 scoped_ptr<TestingProfile> profile_b_; | |
217 scoped_ptr<TemplateURLService> model_b_; | |
218 | |
219 // Our dummy ChangeProcessor used to inspect changes pushed to Sync. | |
220 TestChangeProcessor processor_; | |
221 | |
222 DISALLOW_COPY_AND_ASSIGN(TemplateURLServiceSyncTest); | |
223 }; | |
224 | |
225 TEST_F(TemplateURLServiceSyncTest, SerializeDeserialize) { | |
226 // Create a TemplateURL and convert it into a sync specific type. | |
227 scoped_ptr<TemplateURL> turl(CreateTestTemplateURL()); | |
228 SyncData sync_data = TemplateURLService::CreateSyncDataFromTemplateURL(*turl); | |
229 // Convert the specifics back to a TemplateURL. | |
230 scoped_ptr<TemplateURL> deserialized( | |
231 TemplateURLService::CreateTemplateURLFromSyncData(sync_data)); | |
232 EXPECT_TRUE(deserialized.get()); | |
233 // Ensure that the original and the deserialized TURLs are equal in values. | |
234 AssertEquals(*turl, *deserialized); | |
235 } | |
236 | |
237 TEST_F(TemplateURLServiceSyncTest, GetAllSyncDataBasic) { | |
238 model()->Add(CreateTestTemplateURL("key1", "http://key1.com")); | |
239 model()->Add(CreateTestTemplateURL("key2", "http://key2.com")); | |
240 model()->Add(CreateTestTemplateURL("key3", "http://key3.com")); | |
241 SyncDataList all_sync_data = | |
242 model()->GetAllSyncData(syncable::SEARCH_ENGINES); | |
243 | |
244 EXPECT_EQ(3U, all_sync_data.size()); | |
245 | |
246 for (SyncDataList::const_iterator iter = all_sync_data.begin(); | |
247 iter != all_sync_data.end(); ++iter) { | |
248 std::string guid = GetGUID(*iter); | |
249 const TemplateURL* service_turl = model()->GetTemplateURLForGUID(guid); | |
250 const TemplateURL* deserialized = | |
251 TemplateURLService::CreateTemplateURLFromSyncData(*iter); | |
252 AssertEquals(*service_turl, *deserialized); | |
253 } | |
254 } | |
255 | |
256 TEST_F(TemplateURLServiceSyncTest, GetAllSyncDataNoExtensions) { | |
257 model()->Add(CreateTestTemplateURL("key1", "http://key1.com")); | |
258 model()->Add(CreateTestTemplateURL("key2", "http://key2.com")); | |
259 model()->Add(CreateTestTemplateURL( | |
260 "key3", "chrome-extension://blahblahblah")); | |
261 SyncDataList all_sync_data = | |
262 model()->GetAllSyncData(syncable::SEARCH_ENGINES); | |
263 | |
264 EXPECT_EQ(2U, all_sync_data.size()); | |
265 | |
266 for (SyncDataList::const_iterator iter = all_sync_data.begin(); | |
267 iter != all_sync_data.end(); ++iter) { | |
268 std::string guid = GetGUID(*iter); | |
269 const TemplateURL* service_turl = model()->GetTemplateURLForGUID(guid); | |
270 const TemplateURL* deserialized = | |
271 TemplateURLService::CreateTemplateURLFromSyncData(*iter); | |
272 AssertEquals(*service_turl, *deserialized); | |
273 } | |
274 } | |
275 | |
276 TEST_F(TemplateURLServiceSyncTest, UniquifyKeyword) { | |
277 model()->Add(CreateTestTemplateURL("key1", "http://key1.com")); | |
278 // Create a key that conflicts with something in the model. | |
279 scoped_ptr<TemplateURL> turl(CreateTestTemplateURL("key1", | |
280 "http://new.com", | |
281 "xyz")); | |
282 string16 new_keyword = model()->UniquifyKeyword(*turl); | |
283 | |
284 EXPECT_EQ(UTF8ToUTF16("new.com"), new_keyword); | |
285 EXPECT_EQ(NULL, model()->GetTemplateURLForKeyword(new_keyword)); | |
286 | |
287 turl->set_keyword(new_keyword); | |
288 model()->Add(turl.release()); | |
289 // Test a second collision. This time it should be resolved by actually | |
290 // modifying the original keyword, since the autogenerated keyword is already | |
291 // used. | |
292 turl.reset(CreateTestTemplateURL("key1", "http://new.com")); | |
293 new_keyword = model()->UniquifyKeyword(*turl); | |
294 | |
295 EXPECT_EQ(UTF8ToUTF16("key1_"), new_keyword); | |
296 EXPECT_EQ(NULL, model()->GetTemplateURLForKeyword(new_keyword)); | |
297 | |
298 turl->set_keyword(new_keyword); | |
299 model()->Add(turl.release()); | |
300 // Test a third collision. This should collide on both the autogenerated | |
301 // keyword and the first uniquification attempt. | |
302 turl.reset(CreateTestTemplateURL("key1", "http://new.com")); | |
303 new_keyword = model()->UniquifyKeyword(*turl); | |
304 | |
305 EXPECT_EQ(UTF8ToUTF16("key1__"), new_keyword); | |
306 EXPECT_EQ(NULL, model()->GetTemplateURLForKeyword(new_keyword)); | |
307 } | |
308 | |
309 TEST_F(TemplateURLServiceSyncTest, ResolveSyncKeywordConflict) { | |
310 TemplateURL* original_turl = | |
311 CreateTestTemplateURL("key1", "http://key1.com", "", 9000); | |
312 string16 original_turl_keyword = original_turl->keyword(); | |
313 model()->Add(original_turl); | |
314 | |
315 // Create a key that does not conflict with something in the model. | |
316 scoped_ptr<TemplateURL> sync_turl(CreateTestTemplateURL("unique", | |
317 "http://new.com")); | |
318 string16 sync_keyword = sync_turl->keyword(); | |
319 SyncChangeList changes; | |
320 | |
321 // No conflict, no TURLs changed, no changes. | |
322 EXPECT_FALSE(model()->ResolveSyncKeywordConflict(sync_turl.get(), changes)); | |
323 EXPECT_EQ(original_turl_keyword, original_turl->keyword()); | |
324 EXPECT_EQ(sync_keyword, sync_turl->keyword()); | |
325 EXPECT_EQ(0U, changes.size()); | |
326 | |
327 // Change sync keyword to something that conflicts, and make it older. | |
328 // Conflict, sync keyword is uniquified, and a SyncChange is added. | |
329 sync_turl->set_keyword(original_turl->keyword()); | |
330 sync_turl->set_last_modified(Time::FromTimeT(8999)); | |
331 EXPECT_TRUE(model()->ResolveSyncKeywordConflict(sync_turl.get(), changes)); | |
332 EXPECT_NE(sync_keyword, sync_turl->keyword()); | |
333 EXPECT_EQ(original_turl_keyword, original_turl->keyword()); | |
334 EXPECT_EQ(NULL, model()->GetTemplateURLForKeyword(sync_turl->keyword())); | |
335 EXPECT_EQ(1U, changes.size()); | |
336 changes.clear(); | |
337 | |
338 // Sync is newer. Original TemplateURL keyword is uniquified, no SyncChange | |
339 // is added. | |
340 sync_turl->set_keyword(original_turl->keyword()); | |
341 sync_keyword = sync_turl->keyword(); | |
342 sync_turl->set_last_modified(Time::FromTimeT(9001)); | |
343 EXPECT_TRUE(model()->ResolveSyncKeywordConflict(sync_turl.get(), changes)); | |
344 EXPECT_EQ(sync_keyword, sync_turl->keyword()); | |
345 EXPECT_NE(original_turl_keyword, original_turl->keyword()); | |
346 EXPECT_EQ(NULL, model()->GetTemplateURLForKeyword(sync_turl->keyword())); | |
347 EXPECT_EQ(0U, changes.size()); | |
348 | |
349 // Equal times. Same result as above. Sync left alone, original uniquified so | |
350 // sync_turl can fit. | |
351 sync_turl->set_keyword(original_turl->keyword()); | |
352 sync_keyword = sync_turl->keyword(); | |
353 // Note that we have to reset original_turl's last_modified time as it was | |
354 // modified above. | |
355 original_turl->set_last_modified(Time::FromTimeT(9000)); | |
356 sync_turl->set_last_modified(Time::FromTimeT(9000)); | |
357 EXPECT_TRUE(model()->ResolveSyncKeywordConflict(sync_turl.get(), changes)); | |
358 EXPECT_EQ(sync_keyword, sync_turl->keyword()); | |
359 EXPECT_NE(original_turl_keyword, original_turl->keyword()); | |
360 EXPECT_EQ(NULL, model()->GetTemplateURLForKeyword(sync_turl->keyword())); | |
361 EXPECT_EQ(0U, changes.size()); | |
362 } | |
363 | |
364 TEST_F(TemplateURLServiceSyncTest, FindDuplicateOfSyncTemplateURL) { | |
365 TemplateURL* original_turl = | |
366 CreateTestTemplateURL("key1", "http://key1.com"); | |
367 model()->Add(original_turl); | |
368 | |
369 // No matches at all. | |
370 scoped_ptr<TemplateURL> sync_turl( | |
371 CreateTestTemplateURL("key2", "http://key2.com")); | |
372 EXPECT_EQ(NULL, model()->FindDuplicateOfSyncTemplateURL(*sync_turl)); | |
373 | |
374 // URL matches, but not keyword. No dupe. | |
375 sync_turl->SetURL("http://key1.com", 0 , 0); | |
376 EXPECT_EQ(NULL, model()->FindDuplicateOfSyncTemplateURL(*sync_turl)); | |
377 | |
378 // Keyword matches, but not URL. No dupe. | |
379 sync_turl->SetURL("http://key2.com", 0 , 0); | |
380 sync_turl->set_keyword(UTF8ToUTF16("key1")); | |
381 EXPECT_EQ(NULL, model()->FindDuplicateOfSyncTemplateURL(*sync_turl)); | |
382 | |
383 // Duplicate. | |
384 sync_turl->SetURL("http://key1.com", 0 , 0); | |
385 const TemplateURL* dupe_turl = | |
386 model()->FindDuplicateOfSyncTemplateURL(*sync_turl); | |
387 ASSERT_TRUE(dupe_turl); | |
388 EXPECT_EQ(dupe_turl->keyword(), sync_turl->keyword()); | |
389 EXPECT_EQ(dupe_turl->url()->url(), sync_turl->url()->url()); | |
390 } | |
391 | |
392 TEST_F(TemplateURLServiceSyncTest, MergeSyncAndLocalURLDuplicates) { | |
393 TemplateURL* original_turl = | |
394 CreateTestTemplateURL("key1", "http://key1.com", "", 9000); | |
395 model()->Add(original_turl); | |
396 TemplateURL* sync_turl = | |
397 CreateTestTemplateURL("key1", "http://key1.com", "", 9001); | |
398 SyncChangeList changes; | |
399 | |
400 // The sync TemplateURL is newer. It should replace the original TemplateURL. | |
401 model()->MergeSyncAndLocalURLDuplicates(sync_turl, original_turl, changes); | |
402 EXPECT_EQ(sync_turl, model()->GetTemplateURLForKeyword(sync_turl->keyword())); | |
403 EXPECT_EQ(0U, changes.size()); | |
404 | |
405 // The sync TemplateURL is older. The existing TemplateURL should win and a | |
406 // SyncChange should be added to the list. | |
407 TemplateURL* sync_turl2 = | |
408 CreateTestTemplateURL("key1", "http://key1.com", "", 8999); | |
409 model()->MergeSyncAndLocalURLDuplicates(sync_turl2, sync_turl, changes); | |
410 EXPECT_EQ(sync_turl, | |
411 model()->GetTemplateURLForKeyword(sync_turl2->keyword())); | |
412 EXPECT_EQ(1U, changes.size()); | |
413 } | |
414 | |
415 TEST_F(TemplateURLServiceSyncTest, StartSyncEmpty) { | |
416 model()->MergeDataAndStartSyncing( | |
417 syncable::SEARCH_ENGINES, | |
418 SyncDataList(), // Empty. | |
419 processor()); | |
420 | |
421 EXPECT_EQ(0U, model()->GetAllSyncData(syncable::SEARCH_ENGINES).size()); | |
422 EXPECT_EQ(0, processor()->change_list_size()); | |
423 } | |
424 | |
425 TEST_F(TemplateURLServiceSyncTest, MergeIntoEmpty) { | |
426 SyncDataList initial_data = CreateInitialSyncData(); | |
427 | |
428 model()->MergeDataAndStartSyncing( | |
429 syncable::SEARCH_ENGINES, | |
430 initial_data, | |
431 processor()); | |
432 | |
433 EXPECT_EQ(3U, model()->GetAllSyncData(syncable::SEARCH_ENGINES).size()); | |
434 // We expect the model to have accepted all of the initial sync data. Search | |
435 // through the model using the GUIDs to ensure that they're present. | |
436 for (SyncDataList::const_iterator iter = initial_data.begin(); | |
437 iter != initial_data.end(); ++iter) { | |
438 std::string guid = GetGUID(*iter); | |
439 EXPECT_TRUE(model()->GetTemplateURLForGUID(guid)); | |
440 } | |
441 | |
442 EXPECT_EQ(0, processor()->change_list_size()); | |
443 } | |
444 | |
445 TEST_F(TemplateURLServiceSyncTest, MergeInAllNewData) { | |
446 model()->Add(CreateTestTemplateURL( | |
447 "google.com", "http://google.com", "abc")); | |
448 model()->Add(CreateTestTemplateURL("yahoo.com", "http://yahoo.com", "def")); | |
449 model()->Add(CreateTestTemplateURL("bing.com", "http://bing.com", "xyz")); | |
450 SyncDataList initial_data = CreateInitialSyncData(); | |
451 | |
452 model()->MergeDataAndStartSyncing( | |
453 syncable::SEARCH_ENGINES, | |
454 initial_data, | |
455 processor()); | |
456 | |
457 EXPECT_EQ(6U, model()->GetAllSyncData(syncable::SEARCH_ENGINES).size()); | |
458 // We expect the model to have accepted all of the initial sync data. Search | |
459 // through the model using the GUIDs to ensure that they're present. | |
460 for (SyncDataList::const_iterator iter = initial_data.begin(); | |
461 iter != initial_data.end(); ++iter) { | |
462 std::string guid = GetGUID(*iter); | |
463 EXPECT_TRUE(model()->GetTemplateURLForGUID(guid)); | |
464 } | |
465 // All the original TemplateURLs should also remain in the model. | |
466 EXPECT_TRUE(model()->GetTemplateURLForKeyword(UTF8ToUTF16("google.com"))); | |
467 EXPECT_TRUE(model()->GetTemplateURLForKeyword(UTF8ToUTF16("yahoo.com"))); | |
468 EXPECT_TRUE(model()->GetTemplateURLForKeyword(UTF8ToUTF16("bing.com"))); | |
469 // Ensure that Sync received the expected changes. | |
470 EXPECT_EQ(3, processor()->change_list_size()); | |
471 EXPECT_TRUE(processor()->ContainsGUID("abc")); | |
472 EXPECT_TRUE(processor()->ContainsGUID("def")); | |
473 EXPECT_TRUE(processor()->ContainsGUID("xyz")); | |
474 } | |
475 | |
476 TEST_F(TemplateURLServiceSyncTest, MergeSyncIsTheSame) { | |
477 // The local data is the same as the sync data merged in. i.e. - There have | |
478 // been no changes since the last time we synced. Even the last_modified | |
479 // timestamps are the same. | |
480 SyncDataList initial_data = CreateInitialSyncData(); | |
481 for (SyncDataList::const_iterator iter = initial_data.begin(); | |
482 iter != initial_data.end(); ++iter) { | |
483 TemplateURL* converted = | |
484 TemplateURLService::CreateTemplateURLFromSyncData(*iter); | |
485 model()->Add(converted); | |
486 } | |
487 | |
488 model()->MergeDataAndStartSyncing( | |
489 syncable::SEARCH_ENGINES, | |
490 initial_data, | |
491 processor()); | |
492 | |
493 EXPECT_EQ(3U, model()->GetAllSyncData(syncable::SEARCH_ENGINES).size()); | |
494 for (SyncDataList::const_iterator iter = initial_data.begin(); | |
495 iter != initial_data.end(); ++iter) { | |
496 std::string guid = GetGUID(*iter); | |
497 EXPECT_TRUE(model()->GetTemplateURLForGUID(guid)); | |
498 } | |
499 EXPECT_EQ(0, processor()->change_list_size()); | |
500 } | |
501 | |
502 TEST_F(TemplateURLServiceSyncTest, MergeUpdateFromSync) { | |
503 // The local data is the same as the sync data merged in, but timestamps have | |
504 // changed. Ensure the right fields are merged in. | |
505 SyncDataList initial_data; | |
506 TemplateURL* turl1 = CreateTestTemplateURL( | |
507 "google.com", "http://google.com", "abc", 9000); | |
508 model()->Add(turl1); | |
509 TemplateURL* turl2 = CreateTestTemplateURL( | |
510 "bing.com", "http://bing.com", "xyz", 9000); | |
511 model()->Add(turl2); | |
512 | |
513 TemplateURL turl1_newer(*turl1); | |
514 turl1_newer.set_last_modified(Time::FromTimeT(9999)); | |
515 turl1_newer.SetURL("http://google.ca", 0, 0); | |
516 initial_data.push_back( | |
517 TemplateURLService::CreateSyncDataFromTemplateURL(turl1_newer)); | |
518 | |
519 TemplateURL turl2_older(*turl2); | |
520 turl2_older.set_last_modified(Time::FromTimeT(8888)); | |
521 turl2_older.SetURL("http://bing.ca", 0, 0); | |
522 initial_data.push_back( | |
523 TemplateURLService::CreateSyncDataFromTemplateURL(turl2_older)); | |
524 | |
525 model()->MergeDataAndStartSyncing( | |
526 syncable::SEARCH_ENGINES, | |
527 initial_data, | |
528 processor()); | |
529 | |
530 // Both were local updates, so we expect the same count. | |
531 EXPECT_EQ(2U, model()->GetAllSyncData(syncable::SEARCH_ENGINES).size()); | |
532 | |
533 // Check that the first replaced the initial Google TemplateURL. | |
534 EXPECT_EQ(turl1, model()->GetTemplateURLForGUID("abc")); | |
535 EXPECT_EQ("http://google.ca", turl1->url()->url()); | |
536 | |
537 // Check that the second produced an upstream update to the Bing TemplateURL. | |
538 EXPECT_EQ(1, processor()->change_list_size()); | |
539 ASSERT_TRUE(processor()->ContainsGUID("xyz")); | |
540 SyncChange change = processor()->GetChangeByGUID("xyz"); | |
541 EXPECT_TRUE(change.change_type() == SyncChange::ACTION_UPDATE); | |
542 EXPECT_EQ("http://bing.com", GetURL(change.sync_data())); | |
543 } | |
544 | |
545 TEST_F(TemplateURLServiceSyncTest, MergeAddFromOlderSyncData) { | |
546 // GUIDs all differ, so this is data to be added from Sync, but the timestamps | |
547 // from Sync are older. Set up the local data so that one is a dupe, one has a | |
548 // conflicting keyword, and the last has no conflicts (a clean ADD). | |
549 SyncDataList initial_data = CreateInitialSyncData(); | |
550 TemplateURL* turl = TemplateURLService::CreateTemplateURLFromSyncData( | |
551 initial_data.at(0)); | |
552 ASSERT_TRUE(turl); | |
553 turl->set_sync_guid("aaa"); | |
554 turl->set_last_modified(Time::FromTimeT(100)); | |
555 model()->Add(turl); // dupe | |
556 | |
557 turl = TemplateURLService::CreateTemplateURLFromSyncData( | |
558 initial_data.at(1)); | |
559 ASSERT_TRUE(turl); | |
560 turl->SetURL("http://expected.com", 0, 0); | |
561 turl->set_sync_guid("bbb"); | |
562 turl->set_last_modified(Time::FromTimeT(100)); | |
563 model()->Add(turl); // keyword conflict | |
564 | |
565 model()->Add(CreateTestTemplateURL( | |
566 "unique", "http://unique.com", "ccc")); // add | |
567 | |
568 model()->MergeDataAndStartSyncing( | |
569 syncable::SEARCH_ENGINES, | |
570 initial_data, | |
571 processor()); | |
572 | |
573 // The dupe results in a merge. The other two should be added to the model. | |
574 EXPECT_EQ(5U, model()->GetAllSyncData(syncable::SEARCH_ENGINES).size()); | |
575 | |
576 // The key1 duplicate results in the local copy winning. Ensure that Sync's | |
577 // copy was not added, and the local copy is pushed upstream to Sync as an | |
578 // update. The local copy should have received the sync data's GUID. | |
579 EXPECT_TRUE(model()->GetTemplateURLForGUID("key1")); | |
580 // Check changes for the UPDATE. | |
581 ASSERT_TRUE(processor()->ContainsGUID("key1")); | |
582 SyncChange key1_change = processor()->GetChangeByGUID("key1"); | |
583 EXPECT_EQ(SyncChange::ACTION_UPDATE, key1_change.change_type()); | |
584 EXPECT_FALSE(model()->GetTemplateURLForGUID("aaa")); | |
585 | |
586 // The key2 keyword conflict results in the local copy winning, so ensure it | |
587 // retains the original keyword, and that an update to the sync copy is pushed | |
588 // upstream to Sync. Both TemplateURLs should be found locally, however. | |
589 const TemplateURL* key2 = model()->GetTemplateURLForGUID("bbb"); | |
590 EXPECT_TRUE(key2); | |
591 EXPECT_EQ(UTF8ToUTF16("key2"), key2->keyword()); | |
592 EXPECT_TRUE(model()->GetTemplateURLForGUID("key2")); | |
593 // Check changes for the UPDATE. | |
594 ASSERT_TRUE(processor()->ContainsGUID("key2")); | |
595 SyncChange key2_change = processor()->GetChangeByGUID("key2"); | |
596 EXPECT_EQ(SyncChange::ACTION_UPDATE, key2_change.change_type()); | |
597 EXPECT_EQ("key2.com", GetKeyword(key2_change.sync_data())); | |
598 | |
599 // The last TemplateURL should have had no conflicts and was just added. It | |
600 // should not have replaced the third local TemplateURL. | |
601 EXPECT_TRUE(model()->GetTemplateURLForGUID("ccc")); | |
602 EXPECT_TRUE(model()->GetTemplateURLForGUID("key3")); | |
603 | |
604 // Two UPDATEs and two ADDs. | |
605 EXPECT_EQ(4, processor()->change_list_size()); | |
606 // Two ADDs should be pushed up to Sync. | |
607 ASSERT_TRUE(processor()->ContainsGUID("bbb")); | |
608 EXPECT_EQ(SyncChange::ACTION_ADD, | |
609 processor()->GetChangeByGUID("bbb").change_type()); | |
610 ASSERT_TRUE(processor()->ContainsGUID("ccc")); | |
611 EXPECT_EQ(SyncChange::ACTION_ADD, | |
612 processor()->GetChangeByGUID("ccc").change_type()); | |
613 } | |
614 | |
615 TEST_F(TemplateURLServiceSyncTest, MergeAddFromNewerSyncData) { | |
616 // GUIDs all differ, so this is data to be added from Sync, but the timestamps | |
617 // from Sync are newer. Set up the local data so that one is a dupe, one has a | |
618 // conflicting keyword, and the last has no conflicts (a clean ADD). | |
619 SyncDataList initial_data = CreateInitialSyncData(); | |
620 TemplateURL* turl = TemplateURLService::CreateTemplateURLFromSyncData( | |
621 initial_data.at(0)); | |
622 ASSERT_TRUE(turl); | |
623 turl->set_sync_guid("aaa"); | |
624 turl->set_last_modified(Time::FromTimeT(10)); | |
625 model()->Add(turl); // dupe | |
626 | |
627 turl = TemplateURLService::CreateTemplateURLFromSyncData( | |
628 initial_data.at(1)); | |
629 ASSERT_TRUE(turl); | |
630 turl->SetURL("http://expected.com", 0, 0); | |
631 turl->set_sync_guid("bbb"); | |
632 turl->set_last_modified(Time::FromTimeT(10)); | |
633 model()->Add(turl); // keyword conflict | |
634 | |
635 model()->Add(CreateTestTemplateURL( | |
636 "unique", "http://unique.com", "ccc", 10)); // add | |
637 | |
638 model()->MergeDataAndStartSyncing( | |
639 syncable::SEARCH_ENGINES, | |
640 initial_data, | |
641 processor()); | |
642 | |
643 // The dupe results in a merge. The other two should be added to the model. | |
644 EXPECT_EQ(5U, model()->GetAllSyncData(syncable::SEARCH_ENGINES).size()); | |
645 | |
646 // The key1 duplicate results in Sync's copy winning. Ensure that Sync's | |
647 // copy replaced the local copy. | |
648 EXPECT_TRUE(model()->GetTemplateURLForGUID("key1")); | |
649 EXPECT_FALSE(model()->GetTemplateURLForGUID("aaa")); | |
650 | |
651 // The key2 keyword conflict results in Sync's copy winning, so ensure it | |
652 // retains the original keyword. The local copy should get a uniquified | |
653 // keyword. Both TemplateURLs should be found locally. | |
654 const TemplateURL* key2_sync = model()->GetTemplateURLForGUID("key2"); | |
655 EXPECT_TRUE(key2_sync); | |
656 EXPECT_EQ(UTF8ToUTF16("key2"), key2_sync->keyword()); | |
657 const TemplateURL* key2_local = model()->GetTemplateURLForGUID("bbb"); | |
658 EXPECT_TRUE(key2_local); | |
659 EXPECT_EQ(UTF8ToUTF16("expected.com"), key2_local->keyword()); | |
660 | |
661 // The last TemplateURL should have had no conflicts and was just added. It | |
662 // should not have replaced the third local TemplateURL. | |
663 EXPECT_TRUE(model()->GetTemplateURLForGUID("ccc")); | |
664 EXPECT_TRUE(model()->GetTemplateURLForGUID("key3")); | |
665 | |
666 // Two ADDs. | |
667 EXPECT_EQ(2, processor()->change_list_size()); | |
668 // Two ADDs should be pushed up to Sync. | |
669 ASSERT_TRUE(processor()->ContainsGUID("bbb")); | |
670 EXPECT_EQ(SyncChange::ACTION_ADD, | |
671 processor()->GetChangeByGUID("bbb").change_type()); | |
672 ASSERT_TRUE(processor()->ContainsGUID("ccc")); | |
673 EXPECT_EQ(SyncChange::ACTION_ADD, | |
674 processor()->GetChangeByGUID("ccc").change_type()); | |
675 } | |
676 | |
677 TEST_F(TemplateURLServiceSyncTest, ProcessChangesEmptyModel) { | |
678 // We initially have no data. | |
679 model()->MergeDataAndStartSyncing( | |
680 syncable::SEARCH_ENGINES, | |
681 SyncDataList(), | |
682 processor()); | |
683 | |
684 // Set up a bunch of ADDs. | |
685 SyncChangeList changes; | |
686 changes.push_back(CreateTestSyncChange( | |
687 SyncChange::ACTION_ADD, | |
688 CreateTestTemplateURL("key1", "http://key1.com", "key1"))); | |
689 changes.push_back(CreateTestSyncChange( | |
690 SyncChange::ACTION_ADD, | |
691 CreateTestTemplateURL("key2", "http://key2.com", "key2"))); | |
692 changes.push_back(CreateTestSyncChange( | |
693 SyncChange::ACTION_ADD, | |
694 CreateTestTemplateURL("key3", "http://key3.com", "key3"))); | |
695 | |
696 model()->ProcessSyncChanges(FROM_HERE, changes); | |
697 | |
698 EXPECT_EQ(3U, model()->GetAllSyncData(syncable::SEARCH_ENGINES).size()); | |
699 EXPECT_EQ(0, processor()->change_list_size()); | |
700 EXPECT_TRUE(model()->GetTemplateURLForGUID("key1")); | |
701 EXPECT_TRUE(model()->GetTemplateURLForGUID("key2")); | |
702 EXPECT_TRUE(model()->GetTemplateURLForGUID("key3")); | |
703 } | |
704 | |
705 TEST_F(TemplateURLServiceSyncTest, ProcessChangesNoConflicts) { | |
706 model()->MergeDataAndStartSyncing( | |
707 syncable::SEARCH_ENGINES, | |
708 CreateInitialSyncData(), | |
709 processor()); | |
710 | |
711 // Process different types of changes, without conflicts. | |
712 SyncChangeList changes; | |
713 changes.push_back(CreateTestSyncChange( | |
714 SyncChange::ACTION_ADD, | |
715 CreateTestTemplateURL("key4", "http://key4.com", "key4"))); | |
716 changes.push_back(CreateTestSyncChange( | |
717 SyncChange::ACTION_UPDATE, | |
718 CreateTestTemplateURL("newkeyword", "http://new.com", "key2"))); | |
719 changes.push_back(CreateTestSyncChange( | |
720 SyncChange::ACTION_DELETE, | |
721 CreateTestTemplateURL("key3", "http://key3.com", "key3"))); | |
722 | |
723 model()->ProcessSyncChanges(FROM_HERE, changes); | |
724 | |
725 // Add one, remove one, update one, so the number shouldn't change. | |
726 EXPECT_EQ(3U, model()->GetAllSyncData(syncable::SEARCH_ENGINES).size()); | |
727 EXPECT_EQ(0, processor()->change_list_size()); | |
728 EXPECT_TRUE(model()->GetTemplateURLForGUID("key1")); | |
729 EXPECT_TRUE(model()->GetTemplateURLForGUID("key2")); | |
730 const TemplateURL* turl = model()->GetTemplateURLForGUID("key2"); | |
731 EXPECT_TRUE(turl); | |
732 EXPECT_EQ(UTF8ToUTF16("newkeyword"), turl->keyword()); | |
733 EXPECT_EQ("http://new.com", turl->url()->url()); | |
734 EXPECT_FALSE(model()->GetTemplateURLForGUID("key3")); | |
735 EXPECT_TRUE(model()->GetTemplateURLForGUID("key4")); | |
736 } | |
737 | |
738 TEST_F(TemplateURLServiceSyncTest, ProcessChangesWithConflictsSyncWins) { | |
739 model()->MergeDataAndStartSyncing( | |
740 syncable::SEARCH_ENGINES, | |
741 CreateInitialSyncData(), | |
742 processor()); | |
743 | |
744 // Process different types of changes, with conflicts. Note that all this data | |
745 // has a newer timestamp, so Sync will win in these scenarios. | |
746 SyncChangeList changes; | |
747 changes.push_back(CreateTestSyncChange( | |
748 SyncChange::ACTION_ADD, | |
749 CreateTestTemplateURL("key2", "http://new.com", "aaa"))); | |
750 changes.push_back(CreateTestSyncChange( | |
751 SyncChange::ACTION_UPDATE, | |
752 CreateTestTemplateURL("key3", "http://key3.com", "key1"))); | |
753 | |
754 model()->ProcessSyncChanges(FROM_HERE, changes); | |
755 | |
756 // Add one, update one, so we're up to 4. | |
757 EXPECT_EQ(4U, model()->GetAllSyncData(syncable::SEARCH_ENGINES).size()); | |
758 // Sync is always newer here, so it should always win (i.e. - local changes, | |
759 // nothing pushed to Sync). | |
760 EXPECT_EQ(0, processor()->change_list_size()); | |
761 | |
762 // aaa conflicts with key2 and wins, forcing key2's keyword to update. | |
763 EXPECT_TRUE(model()->GetTemplateURLForGUID("aaa")); | |
764 EXPECT_EQ(model()->GetTemplateURLForGUID("aaa"), | |
765 model()->GetTemplateURLForKeyword(UTF8ToUTF16("key2"))); | |
766 EXPECT_TRUE(model()->GetTemplateURLForGUID("key2")); | |
767 EXPECT_EQ(model()->GetTemplateURLForGUID("key2"), | |
768 model()->GetTemplateURLForKeyword(UTF8ToUTF16("key2.com"))); | |
769 // key1 update conflicts with key3 and wins, forcing key3's keyword to update. | |
770 EXPECT_TRUE(model()->GetTemplateURLForGUID("key1")); | |
771 EXPECT_EQ(model()->GetTemplateURLForGUID("key1"), | |
772 model()->GetTemplateURLForKeyword(UTF8ToUTF16("key3"))); | |
773 EXPECT_TRUE(model()->GetTemplateURLForGUID("key3")); | |
774 EXPECT_EQ(model()->GetTemplateURLForGUID("key3"), | |
775 model()->GetTemplateURLForKeyword(UTF8ToUTF16("key3.com"))); | |
776 } | |
777 | |
778 TEST_F(TemplateURLServiceSyncTest, ProcessChangesWithConflictsLocalWins) { | |
779 model()->MergeDataAndStartSyncing( | |
780 syncable::SEARCH_ENGINES, | |
781 CreateInitialSyncData(), | |
782 processor()); | |
783 | |
784 // Process different types of changes, with conflicts. Note that all this data | |
785 // has an older timestamp, so the local data will win in these scenarios. | |
786 SyncChangeList changes; | |
787 changes.push_back(CreateTestSyncChange( | |
788 SyncChange::ACTION_ADD, | |
789 CreateTestTemplateURL("key2", "http://new.com", "aaa", 10))); | |
790 changes.push_back(CreateTestSyncChange( | |
791 SyncChange::ACTION_UPDATE, | |
792 CreateTestTemplateURL("key3", "http://key3.com", "key1", 10))); | |
793 | |
794 model()->ProcessSyncChanges(FROM_HERE, changes); | |
795 | |
796 // Add one, update one, so we're up to 4. | |
797 EXPECT_EQ(4U, model()->GetAllSyncData(syncable::SEARCH_ENGINES).size()); | |
798 // Local data wins twice so two updates are pushed up to Sync. | |
799 EXPECT_EQ(2, processor()->change_list_size()); | |
800 | |
801 // aaa conflicts with key2 and loses, forcing it's keyword to update. | |
802 EXPECT_TRUE(model()->GetTemplateURLForGUID("aaa")); | |
803 EXPECT_EQ(model()->GetTemplateURLForGUID("aaa"), | |
804 model()->GetTemplateURLForKeyword(UTF8ToUTF16("new.com"))); | |
805 EXPECT_TRUE(model()->GetTemplateURLForGUID("key2")); | |
806 EXPECT_EQ(model()->GetTemplateURLForGUID("key2"), | |
807 model()->GetTemplateURLForKeyword(UTF8ToUTF16("key2"))); | |
808 // key1 update conflicts with key3 and loses, forcing key1's keyword to | |
809 // update. | |
810 EXPECT_TRUE(model()->GetTemplateURLForGUID("key1")); | |
811 EXPECT_EQ(model()->GetTemplateURLForGUID("key1"), | |
812 model()->GetTemplateURLForKeyword(UTF8ToUTF16("key3.com"))); | |
813 EXPECT_TRUE(model()->GetTemplateURLForGUID("key3")); | |
814 EXPECT_EQ(model()->GetTemplateURLForGUID("key3"), | |
815 model()->GetTemplateURLForKeyword(UTF8ToUTF16("key3"))); | |
816 | |
817 ASSERT_TRUE(processor()->ContainsGUID("aaa")); | |
818 EXPECT_EQ(SyncChange::ACTION_UPDATE, | |
819 processor()->GetChangeByGUID("aaa").change_type()); | |
820 ASSERT_TRUE(processor()->ContainsGUID("key1")); | |
821 EXPECT_EQ(SyncChange::ACTION_UPDATE, | |
822 processor()->GetChangeByGUID("key1").change_type()); | |
823 } | |
824 | |
825 TEST_F(TemplateURLServiceSyncTest, ProcessTemplateURLChange) { | |
826 // Ensure that ProcessTemplateURLChange is called and pushes the correct | |
827 // changes to Sync whenever local changes are made to TemplateURLs. | |
828 model()->MergeDataAndStartSyncing( | |
829 syncable::SEARCH_ENGINES, | |
830 CreateInitialSyncData(), | |
831 processor()); | |
832 | |
833 // Add a new search engine. | |
834 TemplateURL* new_turl = | |
835 CreateTestTemplateURL("baidu", "http://baidu.cn", "new"); | |
836 model()->Add(new_turl); | |
837 EXPECT_EQ(1, processor()->change_list_size()); | |
838 ASSERT_TRUE(processor()->ContainsGUID("new")); | |
839 SyncChange change = processor()->GetChangeByGUID("new"); | |
840 EXPECT_EQ(SyncChange::ACTION_ADD, change.change_type()); | |
841 EXPECT_EQ("baidu", GetKeyword(change.sync_data())); | |
842 EXPECT_EQ("http://baidu.cn", GetURL(change.sync_data())); | |
843 | |
844 // Change a keyword. | |
845 const TemplateURL* existing_turl = model()->GetTemplateURLForGUID("key1"); | |
846 model()->ResetTemplateURL(existing_turl, | |
847 existing_turl->short_name(), | |
848 UTF8ToUTF16("k"), | |
849 existing_turl->url()->url()); | |
850 EXPECT_EQ(1, processor()->change_list_size()); | |
851 ASSERT_TRUE(processor()->ContainsGUID("key1")); | |
852 change = processor()->GetChangeByGUID("key1"); | |
853 EXPECT_EQ(SyncChange::ACTION_UPDATE, change.change_type()); | |
854 EXPECT_EQ("k", GetKeyword(change.sync_data())); | |
855 | |
856 // Remove an existing search engine. | |
857 existing_turl = model()->GetTemplateURLForGUID("key2"); | |
858 model()->Remove(existing_turl); | |
859 EXPECT_EQ(1, processor()->change_list_size()); | |
860 ASSERT_TRUE(processor()->ContainsGUID("key2")); | |
861 change = processor()->GetChangeByGUID("key2"); | |
862 EXPECT_EQ(SyncChange::ACTION_DELETE, change.change_type()); | |
863 } | |
864 | |
865 TEST_F(TemplateURLServiceSyncTest, MergeTwoClientsBasic) { | |
866 // Start off B with some empty data. | |
867 model_b()->MergeDataAndStartSyncing( | |
868 syncable::SEARCH_ENGINES, | |
869 CreateInitialSyncData(), | |
870 processor()); | |
871 | |
872 // Merge A and B. All of B's data should transfer over to A, which initially | |
873 // has no data. | |
874 model_a()->MergeDataAndStartSyncing( | |
875 syncable::SEARCH_ENGINES, | |
876 model_b()->GetAllSyncData(syncable::SEARCH_ENGINES), | |
877 model_b()); | |
878 | |
879 // They should be consistent. | |
880 AssertEquals(model_a()->GetAllSyncData(syncable::SEARCH_ENGINES), | |
881 model_b()->GetAllSyncData(syncable::SEARCH_ENGINES)); | |
882 } | |
883 | |
884 TEST_F(TemplateURLServiceSyncTest, MergeTwoClientsDupesAndConflicts) { | |
885 // Start off B with some empty data. | |
886 model_b()->MergeDataAndStartSyncing( | |
887 syncable::SEARCH_ENGINES, | |
888 CreateInitialSyncData(), | |
889 processor()); | |
890 | |
891 // Set up A so we have some interesting duplicates and conflicts. | |
892 model_a()->Add(CreateTestTemplateURL( | |
893 "key4", "http://key4.com", "key4")); // Added | |
894 model_a()->Add(CreateTestTemplateURL( | |
895 "key2", "http://key2.com", "key2")); // Merge - Copy of key2. | |
896 model_a()->Add(CreateTestTemplateURL( | |
897 "key3", "http://key3.com", "key5", 10)); // Merge - Dupe of key3. | |
898 model_a()->Add(CreateTestTemplateURL( | |
899 "key1", "http://key6.com", "key6", 10)); // Keyword conflict with key1 | |
900 | |
901 // Merge A and B. | |
902 model_a()->MergeDataAndStartSyncing( | |
903 syncable::SEARCH_ENGINES, | |
904 model_b()->GetAllSyncData(syncable::SEARCH_ENGINES), | |
905 model_b()); | |
906 | |
907 // They should be consistent. | |
908 AssertEquals(model_a()->GetAllSyncData(syncable::SEARCH_ENGINES), | |
909 model_b()->GetAllSyncData(syncable::SEARCH_ENGINES)); | |
910 } | |
911 | |
912 TEST_F(TemplateURLServiceSyncTest, StopSyncing) { | |
913 SyncError error = model()->MergeDataAndStartSyncing( | |
914 syncable::SEARCH_ENGINES, | |
915 CreateInitialSyncData(), | |
916 processor()); | |
917 ASSERT_FALSE(error.IsSet()); | |
918 model()->StopSyncing(syncable::SEARCH_ENGINES); | |
919 | |
920 SyncChangeList changes; | |
921 changes.push_back(CreateTestSyncChange( | |
922 SyncChange::ACTION_UPDATE, | |
923 CreateTestTemplateURL("newkeyword", "http://new.com", "key2"))); | |
924 error = model()->ProcessSyncChanges(FROM_HERE, changes); | |
925 EXPECT_TRUE(error.IsSet()); | |
926 | |
927 // Ensure that the sync changes were not accepted. | |
928 EXPECT_TRUE(model()->GetTemplateURLForGUID("key2")); | |
929 EXPECT_FALSE(model()->GetTemplateURLForKeyword(UTF8ToUTF16("newkeyword"))); | |
930 } | |
931 | |
932 TEST_F(TemplateURLServiceSyncTest, SyncErrorOnInitialSync) { | |
933 processor()->set_erroneous(true); | |
934 SyncError error = model()->MergeDataAndStartSyncing( | |
935 syncable::SEARCH_ENGINES, | |
936 CreateInitialSyncData(), | |
937 processor()); | |
938 EXPECT_TRUE(error.IsSet()); | |
939 | |
940 SyncChangeList changes; | |
941 changes.push_back(CreateTestSyncChange( | |
942 SyncChange::ACTION_UPDATE, | |
943 CreateTestTemplateURL("newkeyword", "http://new.com", "key2"))); | |
944 processor()->set_erroneous(false); | |
Nicolas Zea
2011/08/15 23:40:00
This is a bit confusing as to why it would trigger
SteveT
2011/08/16 00:08:59
Ah, sorry. I should have put a comment here to exp
| |
945 error = model()->ProcessSyncChanges(FROM_HERE, changes); | |
946 EXPECT_TRUE(error.IsSet()); | |
947 | |
948 // Ensure that the sync changes were not accepted. | |
949 EXPECT_TRUE(model()->GetTemplateURLForGUID("key2")); | |
950 EXPECT_FALSE(model()->GetTemplateURLForKeyword(UTF8ToUTF16("newkeyword"))); | |
951 } | |
952 | |
953 TEST_F(TemplateURLServiceSyncTest, SyncErrorOnLaterSync) { | |
954 SyncError error = model()->MergeDataAndStartSyncing( | |
955 syncable::SEARCH_ENGINES, | |
956 CreateInitialSyncData(), | |
957 processor()); | |
958 ASSERT_FALSE(error.IsSet()); | |
959 | |
960 SyncChangeList changes; | |
961 changes.push_back(CreateTestSyncChange( | |
962 SyncChange::ACTION_UPDATE, | |
963 CreateTestTemplateURL("newkeyword", "http://new.com", "key2"))); | |
964 processor()->set_erroneous(true); | |
965 error = model()->ProcessSyncChanges(FROM_HERE, changes); | |
966 EXPECT_TRUE(error.IsSet()); | |
967 } | |
OLD | NEW |