OLD | NEW |
| (Empty) |
1 // Copyright 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 <stddef.h> | |
6 #include <stdint.h> | |
7 | |
8 #include <memory> | |
9 #include <set> | |
10 #include <string> | |
11 #include <utility> | |
12 #include <vector> | |
13 | |
14 #include "base/bind.h" | |
15 #include "base/bind_helpers.h" | |
16 #include "base/callback.h" | |
17 #include "base/location.h" | |
18 #include "base/macros.h" | |
19 #include "base/memory/ptr_util.h" | |
20 #include "base/memory/ref_counted.h" | |
21 #include "base/run_loop.h" | |
22 #include "base/strings/string16.h" | |
23 #include "base/strings/utf_string_conversions.h" | |
24 #include "base/synchronization/waitable_event.h" | |
25 #include "base/threading/thread.h" | |
26 #include "base/threading/thread_task_runner_handle.h" | |
27 #include "base/time/time.h" | |
28 #include "components/autofill/core/browser/autofill_test_utils.h" | |
29 #include "components/autofill/core/browser/country_names.h" | |
30 #include "components/autofill/core/browser/field_types.h" | |
31 #include "components/autofill/core/browser/personal_data_manager.h" | |
32 #include "components/autofill/core/browser/webdata/autocomplete_syncable_service
.h" | |
33 #include "components/autofill/core/browser/webdata/autofill_change.h" | |
34 #include "components/autofill/core/browser/webdata/autofill_data_type_controller
.h" | |
35 #include "components/autofill/core/browser/webdata/autofill_entry.h" | |
36 #include "components/autofill/core/browser/webdata/autofill_profile_data_type_co
ntroller.h" | |
37 #include "components/autofill/core/browser/webdata/autofill_profile_syncable_ser
vice.h" | |
38 #include "components/autofill/core/browser/webdata/autofill_table.h" | |
39 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h" | |
40 #include "components/autofill/core/common/autofill_pref_names.h" | |
41 #include "components/browser_sync/browser/abstract_profile_sync_service_test.h" | |
42 #include "components/browser_sync/browser/profile_sync_service.h" | |
43 #include "components/browser_sync/browser/test_profile_sync_service.h" | |
44 #include "components/sync/base/model_type.h" | |
45 #include "components/sync/core/data_type_debug_info_listener.h" | |
46 #include "components/sync/core/read_node.h" | |
47 #include "components/sync/core/read_transaction.h" | |
48 #include "components/sync/core/write_node.h" | |
49 #include "components/sync/core/write_transaction.h" | |
50 #include "components/sync/driver/data_type_controller.h" | |
51 #include "components/sync/driver/data_type_manager_impl.h" | |
52 #include "components/sync/driver/sync_api_component_factory_mock.h" | |
53 #include "components/sync/protocol/autofill_specifics.pb.h" | |
54 #include "components/sync/syncable/mutable_entry.h" | |
55 #include "components/sync/syncable/syncable_write_transaction.h" | |
56 #include "components/syncable_prefs/pref_service_syncable.h" | |
57 #include "components/version_info/version_info.h" | |
58 #include "components/webdata/common/web_database.h" | |
59 #include "components/webdata_services/web_data_service_test_util.h" | |
60 #include "testing/gmock/include/gmock/gmock.h" | |
61 #include "testing/gtest/include/gtest/gtest.h" | |
62 | |
63 using autofill::AutocompleteSyncableService; | |
64 using autofill::AutofillChange; | |
65 using autofill::AutofillChangeList; | |
66 using autofill::AutofillEntry; | |
67 using autofill::AutofillKey; | |
68 using autofill::AutofillProfile; | |
69 using autofill::AutofillProfileChange; | |
70 using autofill::AutofillProfileSyncableService; | |
71 using autofill::AutofillTable; | |
72 using autofill::AutofillWebDataService; | |
73 using autofill::NAME_FULL; | |
74 using autofill::PersonalDataManager; | |
75 using autofill::ServerFieldType; | |
76 using base::ASCIIToUTF16; | |
77 using base::Time; | |
78 using base::TimeDelta; | |
79 using base::WaitableEvent; | |
80 using browser_sync::AutofillDataTypeController; | |
81 using browser_sync::AutofillProfileDataTypeController; | |
82 using syncer::AUTOFILL; | |
83 using syncer::AUTOFILL_PROFILE; | |
84 using syncer::BaseNode; | |
85 using syncer::syncable::CREATE; | |
86 using syncer::syncable::GET_TYPE_ROOT; | |
87 using syncer::syncable::MutableEntry; | |
88 using syncer::syncable::UNITTEST; | |
89 using syncer::syncable::WriterTag; | |
90 using syncer::syncable::WriteTransaction; | |
91 using testing::_; | |
92 using testing::DoAll; | |
93 using testing::ElementsAre; | |
94 using testing::Not; | |
95 using testing::SetArgumentPointee; | |
96 using testing::Return; | |
97 | |
98 namespace { | |
99 | |
100 void RegisterAutofillPrefs(user_prefs::PrefRegistrySyncable* registry) { | |
101 registry->RegisterBooleanPref(autofill::prefs::kAutofillEnabled, true); | |
102 registry->RegisterBooleanPref(autofill::prefs::kAutofillWalletImportEnabled, | |
103 true); | |
104 registry->RegisterBooleanPref(autofill::prefs::kAutofillProfileUseDatesFixed, | |
105 true); | |
106 registry->RegisterIntegerPref(autofill::prefs::kAutofillLastVersionDeduped, | |
107 atoi(version_info::GetVersionNumber().c_str())); | |
108 } | |
109 | |
110 void RunAndSignal(const base::Closure& cb, WaitableEvent* event) { | |
111 cb.Run(); | |
112 event->Signal(); | |
113 } | |
114 | |
115 AutofillEntry MakeAutofillEntry(const char* name, | |
116 const char* value, | |
117 int time_shift0, | |
118 int time_shift1) { | |
119 // Time deep in the past would cause Autocomplete sync to discard the | |
120 // entries. | |
121 static Time base_time = Time::Now().LocalMidnight(); | |
122 | |
123 Time date_created = base_time + TimeDelta::FromSeconds(time_shift0); | |
124 Time date_last_used = date_created; | |
125 if (time_shift1 >= 0) | |
126 date_last_used = base_time + TimeDelta::FromSeconds(time_shift1); | |
127 return AutofillEntry(AutofillKey(ASCIIToUTF16(name), ASCIIToUTF16(value)), | |
128 date_created, date_last_used); | |
129 } | |
130 | |
131 AutofillEntry MakeAutofillEntry(const char* name, | |
132 const char* value, | |
133 int time_shift) { | |
134 return MakeAutofillEntry(name, value, time_shift, -1); | |
135 } | |
136 | |
137 } // namespace | |
138 | |
139 class AutofillTableMock : public AutofillTable { | |
140 public: | |
141 AutofillTableMock() {} | |
142 MOCK_METHOD2(RemoveFormElement, | |
143 bool(const base::string16& name, | |
144 const base::string16& value)); // NOLINT | |
145 MOCK_METHOD1(GetAllAutofillEntries, | |
146 bool(std::vector<AutofillEntry>* entries)); // NOLINT | |
147 MOCK_METHOD4(GetAutofillTimestamps, | |
148 bool(const base::string16& name, // NOLINT | |
149 const base::string16& value, | |
150 Time* date_created, | |
151 Time* date_last_used)); | |
152 MOCK_METHOD1(UpdateAutofillEntries, | |
153 bool(const std::vector<AutofillEntry>&)); // NOLINT | |
154 MOCK_METHOD1(GetAutofillProfiles, | |
155 bool(std::vector<AutofillProfile*>*)); // NOLINT | |
156 MOCK_METHOD1(UpdateAutofillProfile, | |
157 bool(const AutofillProfile&)); // NOLINT | |
158 MOCK_METHOD1(AddAutofillProfile, | |
159 bool(const AutofillProfile&)); // NOLINT | |
160 MOCK_METHOD1(RemoveAutofillProfile, | |
161 bool(const std::string&)); // NOLINT | |
162 }; | |
163 | |
164 MATCHER_P(MatchProfiles, profile, "") { | |
165 return (profile.Compare(arg) == 0); | |
166 } | |
167 | |
168 class WebDatabaseFake : public WebDatabase { | |
169 public: | |
170 explicit WebDatabaseFake(AutofillTable* autofill_table) { | |
171 AddTable(autofill_table); | |
172 } | |
173 }; | |
174 | |
175 class MockAutofillBackend : public autofill::AutofillWebDataBackend { | |
176 public: | |
177 MockAutofillBackend( | |
178 WebDatabase* web_database, | |
179 const base::Closure& on_changed, | |
180 const base::Callback<void(syncer::ModelType)>& on_sync_started, | |
181 const scoped_refptr<base::SequencedTaskRunner>& ui_thread) | |
182 : web_database_(web_database), | |
183 on_changed_(on_changed), | |
184 on_sync_started_(on_sync_started), | |
185 ui_thread_(ui_thread) {} | |
186 | |
187 ~MockAutofillBackend() override {} | |
188 WebDatabase* GetDatabase() override { return web_database_; } | |
189 void AddObserver( | |
190 autofill::AutofillWebDataServiceObserverOnDBThread* observer) override {} | |
191 void RemoveObserver( | |
192 autofill::AutofillWebDataServiceObserverOnDBThread* observer) override {} | |
193 void RemoveExpiredFormElements() override {} | |
194 void NotifyOfMultipleAutofillChanges() override { | |
195 DCHECK(!ui_thread_->RunsTasksOnCurrentThread()); | |
196 ui_thread_->PostTask(FROM_HERE, on_changed_); | |
197 } | |
198 void NotifyThatSyncHasStarted(syncer::ModelType model_type) override { | |
199 DCHECK(!ui_thread_->RunsTasksOnCurrentThread()); | |
200 ui_thread_->PostTask(FROM_HERE, base::Bind(on_sync_started_, model_type)); | |
201 } | |
202 | |
203 private: | |
204 WebDatabase* web_database_; | |
205 base::Closure on_changed_; | |
206 base::Callback<void(syncer::ModelType)> on_sync_started_; | |
207 const scoped_refptr<base::SequencedTaskRunner> ui_thread_; | |
208 }; | |
209 | |
210 class ProfileSyncServiceAutofillTest; | |
211 | |
212 template<class AutofillProfile> | |
213 syncer::ModelType GetModelType() { | |
214 return syncer::UNSPECIFIED; | |
215 } | |
216 | |
217 template<> | |
218 syncer::ModelType GetModelType<AutofillEntry>() { | |
219 return AUTOFILL; | |
220 } | |
221 | |
222 template<> | |
223 syncer::ModelType GetModelType<AutofillProfile>() { | |
224 return AUTOFILL_PROFILE; | |
225 } | |
226 | |
227 class TokenWebDataServiceFake : public TokenWebData { | |
228 public: | |
229 TokenWebDataServiceFake( | |
230 const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, | |
231 const scoped_refptr<base::SingleThreadTaskRunner>& db_thread) | |
232 : TokenWebData(ui_thread, db_thread) {} | |
233 | |
234 bool IsDatabaseLoaded() override { return true; } | |
235 | |
236 AutofillWebDataService::Handle GetAllTokens( | |
237 WebDataServiceConsumer* consumer) override { | |
238 // TODO(tim): It would be nice if WebDataService was injected on | |
239 // construction of ProfileOAuth2TokenService rather than fetched by | |
240 // Initialize so that this isn't necessary (we could pass a NULL service). | |
241 // We currently do return it via EXPECT_CALLs, but without depending on | |
242 // order-of-initialization (which seems way more fragile) we can't tell | |
243 // which component is asking at what time, and some components in these | |
244 // Autofill tests require a WebDataService. | |
245 return 0; | |
246 } | |
247 | |
248 private: | |
249 ~TokenWebDataServiceFake() override {} | |
250 | |
251 DISALLOW_COPY_AND_ASSIGN(TokenWebDataServiceFake); | |
252 }; | |
253 | |
254 class WebDataServiceFake : public AutofillWebDataService { | |
255 public: | |
256 WebDataServiceFake( | |
257 const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, | |
258 const scoped_refptr<base::SingleThreadTaskRunner>& db_thread) | |
259 : AutofillWebDataService(ui_thread, db_thread), | |
260 web_database_(NULL), | |
261 autocomplete_syncable_service_(NULL), | |
262 autofill_profile_syncable_service_(NULL), | |
263 syncable_service_created_or_destroyed_( | |
264 base::WaitableEvent::ResetPolicy::AUTOMATIC, | |
265 base::WaitableEvent::InitialState::NOT_SIGNALED), | |
266 db_thread_(db_thread), | |
267 ui_thread_(ui_thread) {} | |
268 | |
269 void SetDatabase(WebDatabase* web_database) { | |
270 web_database_ = web_database; | |
271 } | |
272 | |
273 void StartSyncableService() { | |
274 // The |autofill_profile_syncable_service_| must be constructed on the DB | |
275 // thread. | |
276 const base::Closure& on_changed_callback = base::Bind( | |
277 &WebDataServiceFake::NotifyAutofillMultipleChangedOnUIThread, | |
278 AsWeakPtr()); | |
279 const base::Callback<void(syncer::ModelType)> on_sync_started_callback = | |
280 base::Bind(&WebDataServiceFake::NotifySyncStartedOnUIThread, | |
281 AsWeakPtr()); | |
282 | |
283 db_thread_->PostTask(FROM_HERE, | |
284 base::Bind(&WebDataServiceFake::CreateSyncableService, | |
285 base::Unretained(this), on_changed_callback, | |
286 on_sync_started_callback)); | |
287 syncable_service_created_or_destroyed_.Wait(); | |
288 } | |
289 | |
290 void ShutdownSyncableService() { | |
291 // The |autofill_profile_syncable_service_| must be destructed on the DB | |
292 // thread. | |
293 db_thread_->PostTask(FROM_HERE, | |
294 base::Bind(&WebDataServiceFake::DestroySyncableService, | |
295 base::Unretained(this))); | |
296 syncable_service_created_or_destroyed_.Wait(); | |
297 } | |
298 | |
299 bool IsDatabaseLoaded() override { return true; } | |
300 | |
301 WebDatabase* GetDatabase() override { return web_database_; } | |
302 | |
303 void OnAutofillEntriesChanged(const AutofillChangeList& changes) { | |
304 WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL, | |
305 base::WaitableEvent::InitialState::NOT_SIGNALED); | |
306 | |
307 base::Closure notify_cb = | |
308 base::Bind(&AutocompleteSyncableService::AutofillEntriesChanged, | |
309 base::Unretained(autocomplete_syncable_service_), | |
310 changes); | |
311 db_thread_->PostTask(FROM_HERE, | |
312 base::Bind(&RunAndSignal, notify_cb, &event)); | |
313 event.Wait(); | |
314 } | |
315 | |
316 void OnAutofillProfileChanged(const AutofillProfileChange& changes) { | |
317 WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL, | |
318 base::WaitableEvent::InitialState::NOT_SIGNALED); | |
319 | |
320 base::Closure notify_cb = | |
321 base::Bind(&AutocompleteSyncableService::AutofillProfileChanged, | |
322 base::Unretained(autofill_profile_syncable_service_), | |
323 changes); | |
324 db_thread_->PostTask(FROM_HERE, | |
325 base::Bind(&RunAndSignal, notify_cb, &event)); | |
326 event.Wait(); | |
327 } | |
328 | |
329 private: | |
330 ~WebDataServiceFake() override {} | |
331 | |
332 void CreateSyncableService( | |
333 const base::Closure& on_changed_callback, | |
334 const base::Callback<void(syncer::ModelType)>& on_sync_started) { | |
335 ASSERT_TRUE(db_thread_->RunsTasksOnCurrentThread()); | |
336 // These services are deleted in DestroySyncableService(). | |
337 backend_.reset(new MockAutofillBackend(GetDatabase(), on_changed_callback, | |
338 on_sync_started, ui_thread_.get())); | |
339 AutocompleteSyncableService::CreateForWebDataServiceAndBackend( | |
340 this, backend_.get()); | |
341 AutofillProfileSyncableService::CreateForWebDataServiceAndBackend( | |
342 this, backend_.get(), "en-US"); | |
343 | |
344 autocomplete_syncable_service_ = | |
345 AutocompleteSyncableService::FromWebDataService(this); | |
346 autofill_profile_syncable_service_ = | |
347 AutofillProfileSyncableService::FromWebDataService(this); | |
348 | |
349 syncable_service_created_or_destroyed_.Signal(); | |
350 } | |
351 | |
352 void DestroySyncableService() { | |
353 ASSERT_TRUE(db_thread_->RunsTasksOnCurrentThread()); | |
354 autocomplete_syncable_service_ = NULL; | |
355 autofill_profile_syncable_service_ = NULL; | |
356 backend_.reset(); | |
357 syncable_service_created_or_destroyed_.Signal(); | |
358 } | |
359 | |
360 WebDatabase* web_database_; | |
361 AutocompleteSyncableService* autocomplete_syncable_service_; | |
362 AutofillProfileSyncableService* autofill_profile_syncable_service_; | |
363 std::unique_ptr<autofill::AutofillWebDataBackend> backend_; | |
364 | |
365 WaitableEvent syncable_service_created_or_destroyed_; | |
366 | |
367 const scoped_refptr<base::SingleThreadTaskRunner> db_thread_; | |
368 const scoped_refptr<base::SingleThreadTaskRunner> ui_thread_; | |
369 | |
370 DISALLOW_COPY_AND_ASSIGN(WebDataServiceFake); | |
371 }; | |
372 | |
373 ACTION_P(ReturnNewDataTypeManagerWithDebugListener, debug_listener) { | |
374 return new sync_driver::DataTypeManagerImpl( | |
375 debug_listener, | |
376 arg1, | |
377 arg2, | |
378 arg3, | |
379 arg4); | |
380 } | |
381 | |
382 class MockPersonalDataManager : public PersonalDataManager { | |
383 public: | |
384 MockPersonalDataManager() : PersonalDataManager("en-US") {} | |
385 MOCK_CONST_METHOD0(IsDataLoaded, bool()); | |
386 MOCK_METHOD0(LoadProfiles, void()); | |
387 MOCK_METHOD0(LoadCreditCards, void()); | |
388 MOCK_METHOD0(Refresh, void()); | |
389 }; | |
390 | |
391 template <class T> class AddAutofillHelper; | |
392 | |
393 class ProfileSyncServiceAutofillTest | |
394 : public AbstractProfileSyncServiceTest, | |
395 public syncer::DataTypeDebugInfoListener { | |
396 public: | |
397 // DataTypeDebugInfoListener implementation. | |
398 void OnDataTypeConfigureComplete(const std::vector< | |
399 syncer::DataTypeConfigurationStats>& configuration_stats) override { | |
400 ASSERT_EQ(1u, configuration_stats.size()); | |
401 association_stats_ = configuration_stats[0].association_stats; | |
402 } | |
403 | |
404 protected: | |
405 ProfileSyncServiceAutofillTest() : debug_ptr_factory_(this) { | |
406 autofill::CountryNames::SetLocaleString("en-US"); | |
407 RegisterAutofillPrefs( | |
408 profile_sync_service_bundle()->pref_service()->registry()); | |
409 | |
410 data_type_thread()->Start(); | |
411 profile_sync_service_bundle()->set_db_thread( | |
412 data_type_thread()->task_runner()); | |
413 | |
414 web_database_.reset(new WebDatabaseFake(&autofill_table_)); | |
415 web_data_wrapper_ = base::MakeUnique<MockWebDataServiceWrapper>( | |
416 new WebDataServiceFake(base::ThreadTaskRunnerHandle::Get(), | |
417 data_type_thread()->task_runner()), | |
418 new TokenWebDataServiceFake(base::ThreadTaskRunnerHandle::Get(), | |
419 data_type_thread()->task_runner())); | |
420 web_data_service_ = static_cast<WebDataServiceFake*>( | |
421 web_data_wrapper_->GetAutofillWebData().get()); | |
422 web_data_service_->SetDatabase(web_database_.get()); | |
423 | |
424 personal_data_manager_ = base::MakeUnique<MockPersonalDataManager>(); | |
425 | |
426 EXPECT_CALL(personal_data_manager(), LoadProfiles()); | |
427 EXPECT_CALL(personal_data_manager(), LoadCreditCards()); | |
428 | |
429 personal_data_manager_->Init( | |
430 web_data_service_, profile_sync_service_bundle()->pref_service(), | |
431 profile_sync_service_bundle()->account_tracker(), | |
432 profile_sync_service_bundle()->signin_manager(), false); | |
433 | |
434 web_data_service_->StartSyncableService(); | |
435 | |
436 browser_sync::ProfileSyncServiceBundle::SyncClientBuilder builder( | |
437 profile_sync_service_bundle()); | |
438 builder.SetPersonalDataManager(personal_data_manager_.get()); | |
439 builder.SetSyncServiceCallback(GetSyncServiceCallback()); | |
440 builder.SetSyncableServiceCallback( | |
441 base::Bind(&ProfileSyncServiceAutofillTest::GetSyncableServiceForType, | |
442 base::Unretained(this))); | |
443 builder.set_activate_model_creation(); | |
444 sync_client_owned_ = builder.Build(); | |
445 sync_client_ = sync_client_owned_.get(); | |
446 | |
447 // When UpdateAutofillEntries() is called with an empty list, the return | |
448 // value should be |true|, rather than the default of |false|. | |
449 std::vector<AutofillEntry> empty; | |
450 EXPECT_CALL(autofill_table_, UpdateAutofillEntries(empty)) | |
451 .WillRepeatedly(Return(true)); | |
452 } | |
453 | |
454 ~ProfileSyncServiceAutofillTest() override { | |
455 web_data_service_->ShutdownOnUIThread(); | |
456 web_data_service_->ShutdownSyncableService(); | |
457 web_data_wrapper_->Shutdown(); | |
458 web_data_service_ = nullptr; | |
459 web_data_wrapper_.reset(); | |
460 web_database_.reset(); | |
461 // Shut down the service explicitly before some data members from this | |
462 // test it needs will be deleted. | |
463 sync_service()->Shutdown(); | |
464 } | |
465 | |
466 int GetSyncCount(syncer::ModelType type) { | |
467 syncer::ReadTransaction trans(FROM_HERE, sync_service()->GetUserShare()); | |
468 syncer::ReadNode node(&trans); | |
469 if (node.InitTypeRoot(type) != BaseNode::INIT_OK) | |
470 return 0; | |
471 return node.GetTotalNodeCount() - 1; | |
472 } | |
473 | |
474 void StartSyncService(const base::Closure& callback, | |
475 bool will_fail_association, | |
476 syncer::ModelType type) { | |
477 SigninManagerBase* signin = profile_sync_service_bundle()->signin_manager(); | |
478 signin->SetAuthenticatedAccountInfo("12345", "test_user@gmail.com"); | |
479 CreateSyncService(std::move(sync_client_owned_), callback); | |
480 | |
481 EXPECT_CALL(*profile_sync_service_bundle()->component_factory(), | |
482 CreateDataTypeManager(_, _, _, _, _)) | |
483 .WillOnce(ReturnNewDataTypeManagerWithDebugListener( | |
484 syncer::MakeWeakHandle(debug_ptr_factory_.GetWeakPtr()))); | |
485 | |
486 EXPECT_CALL(personal_data_manager(), IsDataLoaded()) | |
487 .WillRepeatedly(Return(true)); | |
488 | |
489 // We need tokens to get the tests going | |
490 profile_sync_service_bundle()->auth_service()->UpdateCredentials( | |
491 signin->GetAuthenticatedAccountId(), "oauth2_login_token"); | |
492 | |
493 sync_service()->RegisterDataTypeController(CreateDataTypeController(type)); | |
494 sync_service()->Initialize(); | |
495 base::RunLoop().Run(); | |
496 | |
497 // It's possible this test triggered an unrecoverable error, in which case | |
498 // we can't get the sync count. | |
499 if (sync_service()->IsSyncActive()) { | |
500 EXPECT_EQ(GetSyncCount(type), | |
501 association_stats_.num_sync_items_after_association); | |
502 } | |
503 EXPECT_EQ(association_stats_.num_sync_items_after_association, | |
504 association_stats_.num_sync_items_before_association + | |
505 association_stats_.num_sync_items_added - | |
506 association_stats_.num_sync_items_deleted); | |
507 } | |
508 | |
509 bool AddAutofillSyncNode(const AutofillEntry& entry) { | |
510 syncer::WriteTransaction trans(FROM_HERE, sync_service()->GetUserShare()); | |
511 syncer::WriteNode node(&trans); | |
512 std::string tag = AutocompleteSyncableService::KeyToTag( | |
513 base::UTF16ToUTF8(entry.key().name()), | |
514 base::UTF16ToUTF8(entry.key().value())); | |
515 syncer::WriteNode::InitUniqueByCreationResult result = | |
516 node.InitUniqueByCreation(AUTOFILL, tag); | |
517 if (result != syncer::WriteNode::INIT_SUCCESS) | |
518 return false; | |
519 | |
520 sync_pb::EntitySpecifics specifics; | |
521 AutocompleteSyncableService::WriteAutofillEntry(entry, &specifics); | |
522 node.SetEntitySpecifics(specifics); | |
523 return true; | |
524 } | |
525 | |
526 bool AddAutofillSyncNode(const AutofillProfile& profile) { | |
527 syncer::WriteTransaction trans(FROM_HERE, sync_service()->GetUserShare()); | |
528 syncer::WriteNode node(&trans); | |
529 std::string tag = profile.guid(); | |
530 syncer::WriteNode::InitUniqueByCreationResult result = | |
531 node.InitUniqueByCreation(AUTOFILL_PROFILE, tag); | |
532 if (result != syncer::WriteNode::INIT_SUCCESS) | |
533 return false; | |
534 | |
535 sync_pb::EntitySpecifics specifics; | |
536 AutofillProfileSyncableService::WriteAutofillProfile(profile, &specifics); | |
537 node.SetEntitySpecifics(specifics); | |
538 return true; | |
539 } | |
540 | |
541 bool GetAutofillEntriesFromSyncDB(std::vector<AutofillEntry>* entries, | |
542 std::vector<AutofillProfile>* profiles) { | |
543 syncer::ReadTransaction trans(FROM_HERE, sync_service()->GetUserShare()); | |
544 syncer::ReadNode autofill_root(&trans); | |
545 if (autofill_root.InitTypeRoot(AUTOFILL) != BaseNode::INIT_OK) { | |
546 return false; | |
547 } | |
548 | |
549 int64_t child_id = autofill_root.GetFirstChildId(); | |
550 while (child_id != syncer::kInvalidId) { | |
551 syncer::ReadNode child_node(&trans); | |
552 if (child_node.InitByIdLookup(child_id) != BaseNode::INIT_OK) | |
553 return false; | |
554 | |
555 const sync_pb::AutofillSpecifics& autofill( | |
556 child_node.GetEntitySpecifics().autofill()); | |
557 if (autofill.has_value()) { | |
558 AutofillKey key(base::UTF8ToUTF16(autofill.name()), | |
559 base::UTF8ToUTF16(autofill.value())); | |
560 std::vector<Time> timestamps; | |
561 int timestamps_count = autofill.usage_timestamp_size(); | |
562 for (int i = 0; i < timestamps_count; ++i) { | |
563 timestamps.push_back(Time::FromInternalValue( | |
564 autofill.usage_timestamp(i))); | |
565 } | |
566 entries->push_back( | |
567 AutofillEntry(key, timestamps.front(), timestamps.back())); | |
568 } else if (autofill.has_profile()) { | |
569 AutofillProfile p; | |
570 p.set_guid(autofill.profile().guid()); | |
571 AutofillProfileSyncableService::OverwriteProfileWithServerData( | |
572 autofill.profile(), &p); | |
573 profiles->push_back(p); | |
574 } | |
575 child_id = child_node.GetSuccessorId(); | |
576 } | |
577 return true; | |
578 } | |
579 | |
580 bool GetAutofillProfilesFromSyncDBUnderProfileNode( | |
581 std::vector<AutofillProfile>* profiles) { | |
582 syncer::ReadTransaction trans(FROM_HERE, sync_service()->GetUserShare()); | |
583 syncer::ReadNode autofill_root(&trans); | |
584 if (autofill_root.InitTypeRoot(AUTOFILL_PROFILE) != BaseNode::INIT_OK) { | |
585 return false; | |
586 } | |
587 | |
588 int64_t child_id = autofill_root.GetFirstChildId(); | |
589 while (child_id != syncer::kInvalidId) { | |
590 syncer::ReadNode child_node(&trans); | |
591 if (child_node.InitByIdLookup(child_id) != BaseNode::INIT_OK) | |
592 return false; | |
593 | |
594 const sync_pb::AutofillProfileSpecifics& autofill( | |
595 child_node.GetEntitySpecifics().autofill_profile()); | |
596 AutofillProfile p; | |
597 p.set_guid(autofill.guid()); | |
598 AutofillProfileSyncableService::OverwriteProfileWithServerData(autofill, | |
599 &p); | |
600 profiles->push_back(p); | |
601 child_id = child_node.GetSuccessorId(); | |
602 } | |
603 return true; | |
604 } | |
605 | |
606 void SetIdleChangeProcessorExpectations() { | |
607 EXPECT_CALL(autofill_table_, RemoveFormElement(_, _)).Times(0); | |
608 EXPECT_CALL(autofill_table_, GetAutofillTimestamps(_, _, _, _)).Times(0); | |
609 | |
610 // Only permit UpdateAutofillEntries() to be called with an empty list. | |
611 std::vector<AutofillEntry> empty; | |
612 EXPECT_CALL(autofill_table_, UpdateAutofillEntries(Not(empty))).Times(0); | |
613 } | |
614 | |
615 std::unique_ptr<sync_driver::DataTypeController> CreateDataTypeController( | |
616 syncer::ModelType type) { | |
617 DCHECK(type == AUTOFILL || type == AUTOFILL_PROFILE); | |
618 if (type == AUTOFILL) { | |
619 return base::MakeUnique<AutofillDataTypeController>( | |
620 data_type_thread()->task_runner(), base::Bind(&base::DoNothing), | |
621 sync_client_, web_data_service_); | |
622 } else { | |
623 return base::MakeUnique<AutofillProfileDataTypeController>( | |
624 data_type_thread()->task_runner(), base::Bind(&base::DoNothing), | |
625 sync_client_, web_data_service_); | |
626 } | |
627 } | |
628 | |
629 AutofillTableMock& autofill_table() { return autofill_table_; } | |
630 | |
631 MockPersonalDataManager& personal_data_manager() { | |
632 return *personal_data_manager_; | |
633 } | |
634 | |
635 WebDataServiceFake* web_data_service() { return web_data_service_.get(); } | |
636 | |
637 private: | |
638 friend class AddAutofillHelper<AutofillEntry>; | |
639 friend class AddAutofillHelper<AutofillProfile>; | |
640 | |
641 base::WeakPtr<syncer::SyncableService> GetSyncableServiceForType( | |
642 syncer::ModelType type) { | |
643 DCHECK(type == AUTOFILL || type == AUTOFILL_PROFILE); | |
644 if (type == AUTOFILL) { | |
645 return AutocompleteSyncableService::FromWebDataService( | |
646 web_data_service_.get()) | |
647 ->AsWeakPtr(); | |
648 } else { | |
649 return AutofillProfileSyncableService::FromWebDataService( | |
650 web_data_service_.get()) | |
651 ->AsWeakPtr(); | |
652 } | |
653 } | |
654 | |
655 AutofillTableMock autofill_table_; | |
656 std::unique_ptr<WebDatabaseFake> web_database_; | |
657 std::unique_ptr<MockWebDataServiceWrapper> web_data_wrapper_; | |
658 scoped_refptr<WebDataServiceFake> web_data_service_; | |
659 std::unique_ptr<MockPersonalDataManager> personal_data_manager_; | |
660 syncer::DataTypeAssociationStats association_stats_; | |
661 base::WeakPtrFactory<DataTypeDebugInfoListener> debug_ptr_factory_; | |
662 // |sync_client_owned_| keeps the created client until it is passed to the | |
663 // created ProfileSyncService. |sync_client_| just keeps a weak reference to | |
664 // the client the whole time. | |
665 std::unique_ptr<sync_driver::FakeSyncClient> sync_client_owned_; | |
666 sync_driver::FakeSyncClient* sync_client_; | |
667 | |
668 DISALLOW_COPY_AND_ASSIGN(ProfileSyncServiceAutofillTest); | |
669 }; | |
670 | |
671 template <class T> | |
672 class AddAutofillHelper { | |
673 public: | |
674 AddAutofillHelper(ProfileSyncServiceAutofillTest* test, | |
675 const std::vector<T>& entries) | |
676 : callback_(base::Bind(&AddAutofillHelper::AddAutofillCallback, | |
677 base::Unretained(this), test, entries)), | |
678 success_(false) { | |
679 } | |
680 | |
681 const base::Closure& callback() const { return callback_; } | |
682 bool success() { return success_; } | |
683 | |
684 private: | |
685 void AddAutofillCallback(ProfileSyncServiceAutofillTest* test, | |
686 const std::vector<T>& entries) { | |
687 if (!test->CreateRoot(GetModelType<T>())) | |
688 return; | |
689 | |
690 for (size_t i = 0; i < entries.size(); ++i) { | |
691 if (!test->AddAutofillSyncNode(entries[i])) | |
692 return; | |
693 } | |
694 success_ = true; | |
695 } | |
696 | |
697 base::Closure callback_; | |
698 bool success_; | |
699 }; | |
700 | |
701 // Overload write transaction to use custom NotifyTransactionComplete | |
702 class WriteTransactionTest: public WriteTransaction { | |
703 public: | |
704 WriteTransactionTest(const tracked_objects::Location& from_here, | |
705 WriterTag writer, | |
706 syncer::syncable::Directory* directory, | |
707 WaitableEvent* wait_for_syncapi) | |
708 : WriteTransaction(from_here, writer, directory), | |
709 wait_for_syncapi_(wait_for_syncapi) {} | |
710 | |
711 void NotifyTransactionComplete(syncer::ModelTypeSet types) override { | |
712 // This is where we differ. Force a thread change here, giving another | |
713 // thread a chance to create a WriteTransaction | |
714 wait_for_syncapi_->Wait(); | |
715 | |
716 WriteTransaction::NotifyTransactionComplete(types); | |
717 } | |
718 | |
719 private: | |
720 WaitableEvent* const wait_for_syncapi_; | |
721 }; | |
722 | |
723 // Our fake server updater. Needs the RefCountedThreadSafe inheritance so we can | |
724 // post tasks with it. | |
725 class FakeServerUpdater : public base::RefCountedThreadSafe<FakeServerUpdater> { | |
726 public: | |
727 FakeServerUpdater(TestProfileSyncService* service, | |
728 WaitableEvent* wait_for_start, | |
729 WaitableEvent* wait_for_syncapi, | |
730 scoped_refptr<base::SequencedTaskRunner> db_thread) | |
731 : entry_(MakeAutofillEntry("0", "0", 0)), | |
732 service_(service), | |
733 wait_for_start_(wait_for_start), | |
734 wait_for_syncapi_(wait_for_syncapi), | |
735 is_finished_(base::WaitableEvent::ResetPolicy::AUTOMATIC, | |
736 base::WaitableEvent::InitialState::NOT_SIGNALED), | |
737 db_thread_(db_thread) {} | |
738 | |
739 void Update() { | |
740 // This gets called in a modelsafeworker thread. | |
741 ASSERT_TRUE(db_thread_->RunsTasksOnCurrentThread()); | |
742 | |
743 syncer::UserShare* user_share = service_->GetUserShare(); | |
744 syncer::syncable::Directory* directory = user_share->directory.get(); | |
745 | |
746 // Create autofill protobuf. | |
747 std::string tag = AutocompleteSyncableService::KeyToTag( | |
748 base::UTF16ToUTF8(entry_.key().name()), | |
749 base::UTF16ToUTF8(entry_.key().value())); | |
750 sync_pb::AutofillSpecifics new_autofill; | |
751 new_autofill.set_name(base::UTF16ToUTF8(entry_.key().name())); | |
752 new_autofill.set_value(base::UTF16ToUTF8(entry_.key().value())); | |
753 new_autofill.add_usage_timestamp(entry_.date_created().ToInternalValue()); | |
754 if (entry_.date_created() != entry_.date_last_used()) { | |
755 new_autofill.add_usage_timestamp( | |
756 entry_.date_last_used().ToInternalValue()); | |
757 } | |
758 | |
759 sync_pb::EntitySpecifics entity_specifics; | |
760 entity_specifics.mutable_autofill()->CopyFrom(new_autofill); | |
761 | |
762 { | |
763 // Tell main thread we've started | |
764 wait_for_start_->Signal(); | |
765 | |
766 // Create write transaction. | |
767 WriteTransactionTest trans(FROM_HERE, UNITTEST, directory, | |
768 wait_for_syncapi_); | |
769 | |
770 // Create actual entry based on autofill protobuf information. | |
771 // Simulates effects of UpdateLocalDataFromServerData | |
772 MutableEntry parent(&trans, GET_TYPE_ROOT, AUTOFILL); | |
773 MutableEntry item(&trans, CREATE, AUTOFILL, parent.GetId(), tag); | |
774 ASSERT_TRUE(item.good()); | |
775 item.PutSpecifics(entity_specifics); | |
776 item.PutServerSpecifics(entity_specifics); | |
777 item.PutBaseVersion(1); | |
778 syncer::syncable::Id server_item_id = | |
779 service_->id_factory()->NewServerId(); | |
780 item.PutId(server_item_id); | |
781 syncer::syncable::Id new_predecessor; | |
782 ASSERT_TRUE(item.PutPredecessor(new_predecessor)); | |
783 } | |
784 DVLOG(1) << "FakeServerUpdater finishing."; | |
785 is_finished_.Signal(); | |
786 } | |
787 | |
788 void CreateNewEntry(const AutofillEntry& entry) { | |
789 entry_ = entry; | |
790 ASSERT_FALSE(db_thread_->RunsTasksOnCurrentThread()); | |
791 if (!db_thread_->PostTask(FROM_HERE, | |
792 base::Bind(&FakeServerUpdater::Update, this))) { | |
793 NOTREACHED() << "Failed to post task to the db thread."; | |
794 return; | |
795 } | |
796 } | |
797 | |
798 void WaitForUpdateCompletion() { | |
799 is_finished_.Wait(); | |
800 } | |
801 | |
802 private: | |
803 friend class base::RefCountedThreadSafe<FakeServerUpdater>; | |
804 ~FakeServerUpdater() { } | |
805 | |
806 AutofillEntry entry_; | |
807 TestProfileSyncService* service_; | |
808 WaitableEvent* const wait_for_start_; | |
809 WaitableEvent* const wait_for_syncapi_; | |
810 WaitableEvent is_finished_; | |
811 syncer::syncable::Id parent_id_; | |
812 scoped_refptr<base::SequencedTaskRunner> db_thread_; | |
813 | |
814 DISALLOW_COPY_AND_ASSIGN(FakeServerUpdater); | |
815 }; | |
816 | |
817 // TODO(skrul): Test abort startup. | |
818 // TODO(skrul): Test processing of cloud changes. | |
819 // TODO(tim): Add autofill data type controller test, and a case to cover | |
820 // waiting for the PersonalDataManager. | |
821 TEST_F(ProfileSyncServiceAutofillTest, FailModelAssociation) { | |
822 // Don't create the root autofill node so startup fails. | |
823 StartSyncService(base::Closure(), true, AUTOFILL); | |
824 EXPECT_TRUE(sync_service()->HasUnrecoverableError()); | |
825 } | |
826 | |
827 TEST_F(ProfileSyncServiceAutofillTest, EmptyNativeEmptySync) { | |
828 EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_)) | |
829 .WillOnce(Return(true)); | |
830 SetIdleChangeProcessorExpectations(); | |
831 CreateRootHelper create_root(this, AUTOFILL); | |
832 EXPECT_CALL(personal_data_manager(), Refresh()); | |
833 StartSyncService(create_root.callback(), false, AUTOFILL); | |
834 EXPECT_TRUE(create_root.success()); | |
835 std::vector<AutofillEntry> sync_entries; | |
836 std::vector<AutofillProfile> sync_profiles; | |
837 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles)); | |
838 EXPECT_EQ(0U, sync_entries.size()); | |
839 EXPECT_EQ(0U, sync_profiles.size()); | |
840 } | |
841 | |
842 TEST_F(ProfileSyncServiceAutofillTest, HasNativeEntriesEmptySync) { | |
843 std::vector<AutofillEntry> entries; | |
844 entries.push_back(MakeAutofillEntry("foo", "bar", 1)); | |
845 EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_)) | |
846 .WillOnce(DoAll(SetArgumentPointee<0>(entries), Return(true))); | |
847 SetIdleChangeProcessorExpectations(); | |
848 CreateRootHelper create_root(this, AUTOFILL); | |
849 EXPECT_CALL(personal_data_manager(), Refresh()); | |
850 StartSyncService(create_root.callback(), false, AUTOFILL); | |
851 ASSERT_TRUE(create_root.success()); | |
852 std::vector<AutofillEntry> sync_entries; | |
853 std::vector<AutofillProfile> sync_profiles; | |
854 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles)); | |
855 ASSERT_EQ(1U, entries.size()); | |
856 EXPECT_TRUE(entries[0] == sync_entries[0]); | |
857 EXPECT_EQ(0U, sync_profiles.size()); | |
858 } | |
859 | |
860 TEST_F(ProfileSyncServiceAutofillTest, HasProfileEmptySync) { | |
861 std::vector<AutofillProfile*> profiles; | |
862 std::vector<AutofillProfile> expected_profiles; | |
863 // Owned by GetAutofillProfiles caller. | |
864 AutofillProfile* profile0 = new AutofillProfile; | |
865 autofill::test::SetProfileInfoWithGuid(profile0, | |
866 "54B3F9AA-335E-4F71-A27D-719C41564230", "Billing", | |
867 "Mitchell", "Morrison", | |
868 "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA", | |
869 "91601", "US", "12345678910"); | |
870 profiles.push_back(profile0); | |
871 expected_profiles.push_back(*profile0); | |
872 EXPECT_CALL(autofill_table(), GetAutofillProfiles(_)) | |
873 .WillOnce(DoAll(SetArgumentPointee<0>(profiles), Return(true))); | |
874 EXPECT_CALL(personal_data_manager(), Refresh()); | |
875 SetIdleChangeProcessorExpectations(); | |
876 CreateRootHelper create_root(this, AUTOFILL_PROFILE); | |
877 StartSyncService(create_root.callback(), false, AUTOFILL_PROFILE); | |
878 ASSERT_TRUE(create_root.success()); | |
879 std::vector<AutofillProfile> sync_profiles; | |
880 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(&sync_profiles)); | |
881 EXPECT_EQ(1U, sync_profiles.size()); | |
882 EXPECT_EQ(0, expected_profiles[0].Compare(sync_profiles[0])); | |
883 } | |
884 | |
885 TEST_F(ProfileSyncServiceAutofillTest, HasNativeWithDuplicatesEmptySync) { | |
886 // There is buggy autofill code that allows duplicate name/value | |
887 // pairs to exist in the database with separate pair_ids. | |
888 std::vector<AutofillEntry> entries; | |
889 entries.push_back(MakeAutofillEntry("foo", "bar", 1)); | |
890 entries.push_back(MakeAutofillEntry("dup", "", 2)); | |
891 entries.push_back(MakeAutofillEntry("dup", "", 3)); | |
892 EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_)) | |
893 .WillOnce(DoAll(SetArgumentPointee<0>(entries), Return(true))); | |
894 SetIdleChangeProcessorExpectations(); | |
895 CreateRootHelper create_root(this, AUTOFILL); | |
896 EXPECT_CALL(personal_data_manager(), Refresh()); | |
897 StartSyncService(create_root.callback(), false, AUTOFILL); | |
898 ASSERT_TRUE(create_root.success()); | |
899 std::vector<AutofillEntry> sync_entries; | |
900 std::vector<AutofillProfile> sync_profiles; | |
901 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles)); | |
902 EXPECT_EQ(2U, sync_entries.size()); | |
903 } | |
904 | |
905 TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncNoMerge) { | |
906 AutofillEntry native_entry(MakeAutofillEntry("native", "entry", 1)); | |
907 AutofillEntry sync_entry(MakeAutofillEntry("sync", "entry", 2)); | |
908 | |
909 std::vector<AutofillEntry> native_entries; | |
910 native_entries.push_back(native_entry); | |
911 | |
912 EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_)) | |
913 .WillOnce(DoAll(SetArgumentPointee<0>(native_entries), Return(true))); | |
914 | |
915 std::vector<AutofillEntry> sync_entries; | |
916 sync_entries.push_back(sync_entry); | |
917 | |
918 AddAutofillHelper<AutofillEntry> add_autofill(this, sync_entries); | |
919 | |
920 EXPECT_CALL(autofill_table(), UpdateAutofillEntries(ElementsAre(sync_entry))) | |
921 .WillOnce(Return(true)); | |
922 | |
923 EXPECT_CALL(personal_data_manager(), Refresh()); | |
924 StartSyncService(add_autofill.callback(), false, AUTOFILL); | |
925 ASSERT_TRUE(add_autofill.success()); | |
926 | |
927 std::set<AutofillEntry> expected_entries; | |
928 expected_entries.insert(native_entry); | |
929 expected_entries.insert(sync_entry); | |
930 | |
931 std::vector<AutofillEntry> new_sync_entries; | |
932 std::vector<AutofillProfile> new_sync_profiles; | |
933 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries, | |
934 &new_sync_profiles)); | |
935 std::set<AutofillEntry> new_sync_entries_set(new_sync_entries.begin(), | |
936 new_sync_entries.end()); | |
937 | |
938 EXPECT_TRUE(expected_entries == new_sync_entries_set); | |
939 } | |
940 | |
941 TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncMergeEntry) { | |
942 AutofillEntry native_entry(MakeAutofillEntry("merge", "entry", 1)); | |
943 AutofillEntry sync_entry(MakeAutofillEntry("merge", "entry", 2)); | |
944 AutofillEntry merged_entry(MakeAutofillEntry("merge", "entry", 1, 2)); | |
945 | |
946 std::vector<AutofillEntry> native_entries; | |
947 native_entries.push_back(native_entry); | |
948 EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_)) | |
949 .WillOnce(DoAll(SetArgumentPointee<0>(native_entries), Return(true))); | |
950 | |
951 std::vector<AutofillEntry> sync_entries; | |
952 sync_entries.push_back(sync_entry); | |
953 AddAutofillHelper<AutofillEntry> add_autofill(this, sync_entries); | |
954 | |
955 EXPECT_CALL(autofill_table(), | |
956 UpdateAutofillEntries(ElementsAre(merged_entry))) | |
957 .WillOnce(Return(true)); | |
958 EXPECT_CALL(personal_data_manager(), Refresh()); | |
959 StartSyncService(add_autofill.callback(), false, AUTOFILL); | |
960 ASSERT_TRUE(add_autofill.success()); | |
961 | |
962 std::vector<AutofillEntry> new_sync_entries; | |
963 std::vector<AutofillProfile> new_sync_profiles; | |
964 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries, | |
965 &new_sync_profiles)); | |
966 ASSERT_EQ(1U, new_sync_entries.size()); | |
967 EXPECT_TRUE(merged_entry == new_sync_entries[0]); | |
968 } | |
969 | |
970 TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncMergeProfile) { | |
971 AutofillProfile sync_profile; | |
972 autofill::test::SetProfileInfoWithGuid(&sync_profile, | |
973 "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing", | |
974 "Mitchell", "Morrison", | |
975 "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA", | |
976 "91601", "US", "12345678910"); | |
977 | |
978 AutofillProfile* native_profile = new AutofillProfile; | |
979 autofill::test::SetProfileInfoWithGuid(native_profile, | |
980 "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing", "Alicia", "Saenz", | |
981 "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL", | |
982 "32801", "US", "19482937549"); | |
983 | |
984 std::vector<AutofillProfile*> native_profiles; | |
985 native_profiles.push_back(native_profile); | |
986 EXPECT_CALL(autofill_table(), GetAutofillProfiles(_)) | |
987 .WillOnce(DoAll(SetArgumentPointee<0>(native_profiles), Return(true))); | |
988 | |
989 std::vector<AutofillProfile> sync_profiles; | |
990 sync_profiles.push_back(sync_profile); | |
991 AddAutofillHelper<AutofillProfile> add_autofill(this, sync_profiles); | |
992 | |
993 EXPECT_CALL(autofill_table(), | |
994 UpdateAutofillProfile(MatchProfiles(sync_profile))) | |
995 .WillOnce(Return(true)); | |
996 EXPECT_CALL(personal_data_manager(), Refresh()); | |
997 StartSyncService(add_autofill.callback(), false, AUTOFILL_PROFILE); | |
998 ASSERT_TRUE(add_autofill.success()); | |
999 | |
1000 std::vector<AutofillProfile> new_sync_profiles; | |
1001 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode( | |
1002 &new_sync_profiles)); | |
1003 ASSERT_EQ(1U, new_sync_profiles.size()); | |
1004 EXPECT_EQ(0, sync_profile.Compare(new_sync_profiles[0])); | |
1005 } | |
1006 | |
1007 // Tests that a sync with a new native profile that matches a more recent new | |
1008 // sync profile but with less information results in the native profile being | |
1009 // deleted and replaced by the sync profile with merged usage stats. | |
1010 TEST_F( | |
1011 ProfileSyncServiceAutofillTest, | |
1012 HasNativeHasSyncMergeSimilarProfileCombine_SyncHasMoreInfoAndMoreRecent) { | |
1013 // Create two almost identical profiles. The GUIDs are different and the | |
1014 // native profile has no value for company name. | |
1015 AutofillProfile sync_profile; | |
1016 autofill::test::SetProfileInfoWithGuid( | |
1017 &sync_profile, "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing", | |
1018 "Mitchell", "Morrison", "johnwayne@me.xyz", "Fox", "123 Zoo St.", | |
1019 "unit 5", "Hollywood", "CA", "91601", "US", "12345678910"); | |
1020 sync_profile.set_use_date(base::Time::FromTimeT(4321)); | |
1021 | |
1022 AutofillProfile* native_profile = new AutofillProfile; | |
1023 autofill::test::SetProfileInfoWithGuid( | |
1024 native_profile, "23355099-1170-4B71-8ED4-144470CC9EBF", "Billing", | |
1025 "Mitchell", "Morrison", "johnwayne@me.xyz", "", "123 Zoo St.", "unit 5", | |
1026 "Hollywood", "CA", "91601", "US", "12345678910"); | |
1027 native_profile->set_use_date(base::Time::FromTimeT(1234)); | |
1028 | |
1029 AutofillProfile expected_profile(sync_profile); | |
1030 expected_profile.SetRawInfo(NAME_FULL, | |
1031 ASCIIToUTF16("Billing Mitchell Morrison")); | |
1032 expected_profile.set_use_count(1); | |
1033 | |
1034 std::vector<AutofillProfile*> native_profiles; | |
1035 native_profiles.push_back(native_profile); | |
1036 EXPECT_CALL(autofill_table(), GetAutofillProfiles(_)) | |
1037 .WillOnce(DoAll(SetArgumentPointee<0>(native_profiles), Return(true))); | |
1038 EXPECT_CALL(autofill_table(), | |
1039 AddAutofillProfile(MatchProfiles(expected_profile))) | |
1040 .WillOnce(Return(true)); | |
1041 EXPECT_CALL(autofill_table(), | |
1042 RemoveAutofillProfile("23355099-1170-4B71-8ED4-144470CC9EBF")) | |
1043 .WillOnce(Return(true)); | |
1044 std::vector<AutofillProfile> sync_profiles; | |
1045 sync_profiles.push_back(sync_profile); | |
1046 AddAutofillHelper<AutofillProfile> add_autofill(this, sync_profiles); | |
1047 | |
1048 EXPECT_CALL(personal_data_manager(), Refresh()); | |
1049 // Adds all entries in |sync_profiles| to sync. | |
1050 StartSyncService(add_autofill.callback(), false, AUTOFILL_PROFILE); | |
1051 ASSERT_TRUE(add_autofill.success()); | |
1052 | |
1053 std::vector<AutofillProfile> new_sync_profiles; | |
1054 ASSERT_TRUE( | |
1055 GetAutofillProfilesFromSyncDBUnderProfileNode(&new_sync_profiles)); | |
1056 ASSERT_EQ(1U, new_sync_profiles.size()); | |
1057 // Check that key fields are the same. | |
1058 EXPECT_TRUE(new_sync_profiles[0].IsSubsetOf(sync_profile, "en-US")); | |
1059 // Make sure the additional information from the sync profile was kept. | |
1060 EXPECT_EQ(ASCIIToUTF16("Fox"), | |
1061 new_sync_profiles[0].GetRawInfo(ServerFieldType::COMPANY_NAME)); | |
1062 // Check that the latest use date is saved. | |
1063 EXPECT_EQ(base::Time::FromTimeT(4321), new_sync_profiles[0].use_date()); | |
1064 // Check that the use counts were added (default value is 1). | |
1065 EXPECT_EQ(1U, new_sync_profiles[0].use_count()); | |
1066 } | |
1067 | |
1068 // Tests that a sync with a new native profile that matches an older new sync | |
1069 // profile but with less information results in the native profile being deleted | |
1070 // and replaced by the sync profile with merged usage stats. | |
1071 TEST_F(ProfileSyncServiceAutofillTest, | |
1072 HasNativeHasSyncMergeSimilarProfileCombine_SyncHasMoreInfoAndOlder) { | |
1073 // Create two almost identical profiles. The GUIDs are different and the | |
1074 // native profile has no value for company name. | |
1075 AutofillProfile sync_profile; | |
1076 autofill::test::SetProfileInfoWithGuid( | |
1077 &sync_profile, "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing", | |
1078 "Mitchell", "Morrison", "johnwayne@me.xyz", "Fox", "123 Zoo St.", | |
1079 "unit 5", "Hollywood", "CA", "91601", "US", "12345678910"); | |
1080 sync_profile.set_use_date(base::Time::FromTimeT(1234)); | |
1081 | |
1082 AutofillProfile* native_profile = new AutofillProfile; | |
1083 autofill::test::SetProfileInfoWithGuid( | |
1084 native_profile, "23355099-1170-4B71-8ED4-144470CC9EBF", "Billing", | |
1085 "Mitchell", "Morrison", "johnwayne@me.xyz", "", "123 Zoo St.", "unit 5", | |
1086 "Hollywood", "CA", "91601", "US", "12345678910"); | |
1087 native_profile->set_use_date(base::Time::FromTimeT(4321)); | |
1088 | |
1089 AutofillProfile expected_profile(sync_profile); | |
1090 expected_profile.SetRawInfo(NAME_FULL, | |
1091 ASCIIToUTF16("Billing Mitchell Morrison")); | |
1092 expected_profile.set_use_count(1); | |
1093 expected_profile.set_use_date(native_profile->use_date()); | |
1094 | |
1095 std::vector<AutofillProfile*> native_profiles; | |
1096 native_profiles.push_back(native_profile); | |
1097 EXPECT_CALL(autofill_table(), GetAutofillProfiles(_)) | |
1098 .WillOnce(DoAll(SetArgumentPointee<0>(native_profiles), Return(true))); | |
1099 EXPECT_CALL(autofill_table(), | |
1100 AddAutofillProfile(MatchProfiles(expected_profile))) | |
1101 .WillOnce(Return(true)); | |
1102 EXPECT_CALL(autofill_table(), | |
1103 RemoveAutofillProfile("23355099-1170-4B71-8ED4-144470CC9EBF")) | |
1104 .WillOnce(Return(true)); | |
1105 std::vector<AutofillProfile> sync_profiles; | |
1106 sync_profiles.push_back(sync_profile); | |
1107 AddAutofillHelper<AutofillProfile> add_autofill(this, sync_profiles); | |
1108 | |
1109 EXPECT_CALL(personal_data_manager(), Refresh()); | |
1110 // Adds all entries in |sync_profiles| to sync. | |
1111 StartSyncService(add_autofill.callback(), false, AUTOFILL_PROFILE); | |
1112 ASSERT_TRUE(add_autofill.success()); | |
1113 | |
1114 std::vector<AutofillProfile> new_sync_profiles; | |
1115 ASSERT_TRUE( | |
1116 GetAutofillProfilesFromSyncDBUnderProfileNode(&new_sync_profiles)); | |
1117 ASSERT_EQ(1U, new_sync_profiles.size()); | |
1118 // Check that key fields are the same. | |
1119 EXPECT_TRUE(new_sync_profiles[0].IsSubsetOf(sync_profile, "en-US")); | |
1120 // Make sure the additional information from the sync profile was kept. | |
1121 EXPECT_EQ(ASCIIToUTF16("Fox"), | |
1122 new_sync_profiles[0].GetRawInfo(ServerFieldType::COMPANY_NAME)); | |
1123 // Check that the latest use date is saved. | |
1124 EXPECT_EQ(base::Time::FromTimeT(4321), new_sync_profiles[0].use_date()); | |
1125 // Check that the use counts were added (default value is 1). | |
1126 EXPECT_EQ(1U, new_sync_profiles[0].use_count()); | |
1127 } | |
1128 | |
1129 // Tests that a sync with a new native profile that matches an a new sync | |
1130 // profile but with more information results in the native profile being deleted | |
1131 // and replaced by the sync profile with the native profiles additional | |
1132 // information merged in. The merge should happen even if the sync profile is | |
1133 // more recent. | |
1134 TEST_F(ProfileSyncServiceAutofillTest, | |
1135 HasNativeHasSyncMergeSimilarProfileCombine_NativeHasMoreInfo) { | |
1136 // Create two almost identical profiles. The GUIDs are different and the | |
1137 // sync profile has no value for company name. | |
1138 AutofillProfile sync_profile; | |
1139 autofill::test::SetProfileInfoWithGuid( | |
1140 &sync_profile, "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing", | |
1141 "Mitchell", "Morrison", "johnwayne@me.xyz", "", "123 Zoo St.", "unit 5", | |
1142 "Hollywood", "CA", "91601", "US", "12345678910"); | |
1143 sync_profile.set_use_date(base::Time::FromTimeT(4321)); | |
1144 | |
1145 AutofillProfile* native_profile = new AutofillProfile; | |
1146 autofill::test::SetProfileInfoWithGuid( | |
1147 native_profile, "23355099-1170-4B71-8ED4-144470CC9EBF", "Billing", | |
1148 "Mitchell", "Morrison", "johnwayne@me.xyz", "Fox", "123 Zoo St.", | |
1149 "unit 5", "Hollywood", "CA", "91601", "US", "12345678910"); | |
1150 native_profile->set_use_date(base::Time::FromTimeT(1234)); | |
1151 | |
1152 AutofillProfile expected_profile(*native_profile); | |
1153 expected_profile.SetRawInfo(NAME_FULL, | |
1154 ASCIIToUTF16("Billing Mitchell Morrison")); | |
1155 expected_profile.set_use_date(sync_profile.use_date()); | |
1156 expected_profile.set_use_count(1); | |
1157 | |
1158 std::vector<AutofillProfile*> native_profiles; | |
1159 native_profiles.push_back(native_profile); | |
1160 EXPECT_CALL(autofill_table(), GetAutofillProfiles(_)) | |
1161 .WillOnce(DoAll(SetArgumentPointee<0>(native_profiles), Return(true))); | |
1162 EXPECT_CALL(autofill_table(), | |
1163 AddAutofillProfile(MatchProfiles(expected_profile))) | |
1164 .WillOnce(Return(true)); | |
1165 EXPECT_CALL(autofill_table(), | |
1166 RemoveAutofillProfile("23355099-1170-4B71-8ED4-144470CC9EBF")) | |
1167 .WillOnce(Return(true)); | |
1168 std::vector<AutofillProfile> sync_profiles; | |
1169 sync_profiles.push_back(sync_profile); | |
1170 AddAutofillHelper<AutofillProfile> add_autofill(this, sync_profiles); | |
1171 | |
1172 EXPECT_CALL(personal_data_manager(), Refresh()); | |
1173 // Adds all entries in |sync_profiles| to sync. | |
1174 StartSyncService(add_autofill.callback(), false, AUTOFILL_PROFILE); | |
1175 ASSERT_TRUE(add_autofill.success()); | |
1176 | |
1177 std::vector<AutofillProfile> new_sync_profiles; | |
1178 ASSERT_TRUE( | |
1179 GetAutofillProfilesFromSyncDBUnderProfileNode(&new_sync_profiles)); | |
1180 ASSERT_EQ(1U, new_sync_profiles.size()); | |
1181 // Check that key fields are the same. | |
1182 EXPECT_TRUE(new_sync_profiles[0].IsSubsetOf(expected_profile, "en-US")); | |
1183 // Make sure the addtional information of the native profile was saved into | |
1184 // the sync profile. | |
1185 EXPECT_EQ(ASCIIToUTF16("Fox"), | |
1186 new_sync_profiles[0].GetRawInfo(ServerFieldType::COMPANY_NAME)); | |
1187 // Check that the latest use date is saved. | |
1188 EXPECT_EQ(base::Time::FromTimeT(4321), new_sync_profiles[0].use_date()); | |
1189 // Check that the use counts were added (default value is 1). | |
1190 EXPECT_EQ(1U, new_sync_profiles[0].use_count()); | |
1191 } | |
1192 | |
1193 // Tests that a sync with a new native profile that differ only by name a new | |
1194 // sync profile results in keeping both profiles. | |
1195 TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSync_DifferentPrimaryInfo) { | |
1196 AutofillProfile sync_profile; | |
1197 autofill::test::SetProfileInfoWithGuid( | |
1198 &sync_profile, "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing", | |
1199 "Mitchell", "Morrison", "johnwayne@me.xyz", "Fox", "123 Zoo St.", | |
1200 "unit 5", "Hollywood", "CA", "91601", "US", "12345678910"); | |
1201 sync_profile.set_use_date(base::Time::FromTimeT(4321)); | |
1202 | |
1203 AutofillProfile* native_profile = new AutofillProfile; | |
1204 autofill::test::SetProfileInfoWithGuid( | |
1205 native_profile, "23355099-1170-4B71-8ED4-144470CC9EBF", "Billing", "John", | |
1206 "Smith", "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", | |
1207 "CA", "91601", "US", "12345678910"); | |
1208 native_profile->set_use_date(base::Time::FromTimeT(1234)); | |
1209 | |
1210 std::vector<AutofillProfile*> native_profiles; | |
1211 native_profiles.push_back(native_profile); | |
1212 EXPECT_CALL(autofill_table(), GetAutofillProfiles(_)) | |
1213 .WillOnce(DoAll(SetArgumentPointee<0>(native_profiles), Return(true))); | |
1214 EXPECT_CALL(autofill_table(), AddAutofillProfile(MatchProfiles(sync_profile))) | |
1215 .WillOnce(Return(true)); | |
1216 std::vector<AutofillProfile> sync_profiles; | |
1217 sync_profiles.push_back(sync_profile); | |
1218 AddAutofillHelper<AutofillProfile> add_autofill(this, sync_profiles); | |
1219 | |
1220 EXPECT_CALL(personal_data_manager(), Refresh()); | |
1221 // Adds all entries in |sync_profiles| to sync. | |
1222 StartSyncService(add_autofill.callback(), false, AUTOFILL_PROFILE); | |
1223 ASSERT_TRUE(add_autofill.success()); | |
1224 | |
1225 std::vector<AutofillProfile> new_sync_profiles; | |
1226 ASSERT_TRUE( | |
1227 GetAutofillProfilesFromSyncDBUnderProfileNode(&new_sync_profiles)); | |
1228 // The two profiles should be kept. | |
1229 ASSERT_EQ(2U, new_sync_profiles.size()); | |
1230 } | |
1231 | |
1232 // Tests that a new native profile that is the same as a new sync profile except | |
1233 // with different GUIDs results in the native profile being deleted and replaced | |
1234 // by the sync profile. | |
1235 TEST_F(ProfileSyncServiceAutofillTest, MergeProfileWithDifferentGuid) { | |
1236 AutofillProfile sync_profile; | |
1237 | |
1238 autofill::test::SetProfileInfoWithGuid(&sync_profile, | |
1239 "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing", | |
1240 "Mitchell", "Morrison", | |
1241 "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA", | |
1242 "91601", "US", "12345678910"); | |
1243 sync_profile.set_use_count(20); | |
1244 sync_profile.set_use_date(base::Time::FromTimeT(1234)); | |
1245 | |
1246 std::string native_guid = "EDC609ED-7EEE-4F27-B00C-423242A9C44B"; | |
1247 AutofillProfile* native_profile = new AutofillProfile; | |
1248 autofill::test::SetProfileInfoWithGuid(native_profile, | |
1249 native_guid.c_str(), "Billing", | |
1250 "Mitchell", "Morrison", | |
1251 "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA", | |
1252 "91601", "US", "12345678910"); | |
1253 native_profile->set_use_count(5); | |
1254 native_profile->set_use_date(base::Time::FromTimeT(4321)); | |
1255 | |
1256 std::vector<AutofillProfile*> native_profiles; | |
1257 native_profiles.push_back(native_profile); | |
1258 EXPECT_CALL(autofill_table(), GetAutofillProfiles(_)) | |
1259 .WillOnce(DoAll(SetArgumentPointee<0>(native_profiles), Return(true))); | |
1260 | |
1261 std::vector<AutofillProfile> sync_profiles; | |
1262 sync_profiles.push_back(sync_profile); | |
1263 AddAutofillHelper<AutofillProfile> add_autofill(this, sync_profiles); | |
1264 | |
1265 EXPECT_CALL(autofill_table(), AddAutofillProfile(_)).WillOnce(Return(true)); | |
1266 EXPECT_CALL(autofill_table(), RemoveAutofillProfile(native_guid)) | |
1267 .WillOnce(Return(true)); | |
1268 EXPECT_CALL(personal_data_manager(), Refresh()); | |
1269 StartSyncService(add_autofill.callback(), false, AUTOFILL_PROFILE); | |
1270 ASSERT_TRUE(add_autofill.success()); | |
1271 | |
1272 std::vector<AutofillProfile> new_sync_profiles; | |
1273 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode( | |
1274 &new_sync_profiles)); | |
1275 // Check that the profiles were merged. | |
1276 ASSERT_EQ(1U, new_sync_profiles.size()); | |
1277 EXPECT_EQ(0, sync_profile.Compare(new_sync_profiles[0])); | |
1278 // Check that the sync guid was kept. | |
1279 EXPECT_EQ(sync_profile.guid(), new_sync_profiles[0].guid()); | |
1280 // Check that the sync profile use count was kept. | |
1281 EXPECT_EQ(20U, new_sync_profiles[0].use_count()); | |
1282 // Check that the sync profile use date was kept. | |
1283 EXPECT_EQ(base::Time::FromTimeT(1234), new_sync_profiles[0].use_date()); | |
1284 } | |
1285 | |
1286 TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeAddEntry) { | |
1287 EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_)) | |
1288 .WillOnce(Return(true)); | |
1289 EXPECT_CALL(personal_data_manager(), Refresh()); | |
1290 SetIdleChangeProcessorExpectations(); | |
1291 CreateRootHelper create_root(this, AUTOFILL); | |
1292 StartSyncService(create_root.callback(), false, AUTOFILL); | |
1293 ASSERT_TRUE(create_root.success()); | |
1294 | |
1295 AutofillEntry added_entry(MakeAutofillEntry("added", "entry", 1)); | |
1296 | |
1297 EXPECT_CALL(autofill_table(), GetAutofillTimestamps(_, _, _, _)) | |
1298 .WillOnce(DoAll(SetArgumentPointee<2>(added_entry.date_created()), | |
1299 SetArgumentPointee<3>(added_entry.date_last_used()), | |
1300 Return(true))); | |
1301 | |
1302 AutofillChangeList changes; | |
1303 changes.push_back(AutofillChange(AutofillChange::ADD, added_entry.key())); | |
1304 | |
1305 web_data_service()->OnAutofillEntriesChanged(changes); | |
1306 | |
1307 std::vector<AutofillEntry> new_sync_entries; | |
1308 std::vector<AutofillProfile> new_sync_profiles; | |
1309 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries, | |
1310 &new_sync_profiles)); | |
1311 ASSERT_EQ(1U, new_sync_entries.size()); | |
1312 EXPECT_TRUE(added_entry == new_sync_entries[0]); | |
1313 } | |
1314 | |
1315 TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeAddProfile) { | |
1316 EXPECT_CALL(autofill_table(), GetAutofillProfiles(_)).WillOnce(Return(true)); | |
1317 EXPECT_CALL(personal_data_manager(), Refresh()); | |
1318 SetIdleChangeProcessorExpectations(); | |
1319 CreateRootHelper create_root(this, AUTOFILL_PROFILE); | |
1320 StartSyncService(create_root.callback(), false, AUTOFILL_PROFILE); | |
1321 ASSERT_TRUE(create_root.success()); | |
1322 | |
1323 AutofillProfile added_profile; | |
1324 autofill::test::SetProfileInfoWithGuid(&added_profile, | |
1325 "D6ADA912-D374-4C0A-917D-F5C8EBE43011", "Josephine", "Alicia", "Saenz", | |
1326 "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL", | |
1327 "32801", "US", "19482937549"); | |
1328 | |
1329 AutofillProfileChange change( | |
1330 AutofillProfileChange::ADD, added_profile.guid(), &added_profile); | |
1331 web_data_service()->OnAutofillProfileChanged(change); | |
1332 | |
1333 std::vector<AutofillProfile> new_sync_profiles; | |
1334 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode( | |
1335 &new_sync_profiles)); | |
1336 ASSERT_EQ(1U, new_sync_profiles.size()); | |
1337 EXPECT_EQ(0, added_profile.Compare(new_sync_profiles[0])); | |
1338 } | |
1339 | |
1340 TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeUpdateEntry) { | |
1341 AutofillEntry original_entry(MakeAutofillEntry("my", "entry", 1)); | |
1342 std::vector<AutofillEntry> original_entries; | |
1343 original_entries.push_back(original_entry); | |
1344 | |
1345 EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_)) | |
1346 .WillOnce(DoAll(SetArgumentPointee<0>(original_entries), Return(true))); | |
1347 EXPECT_CALL(personal_data_manager(), Refresh()); | |
1348 CreateRootHelper create_root(this, AUTOFILL); | |
1349 StartSyncService(create_root.callback(), false, AUTOFILL); | |
1350 ASSERT_TRUE(create_root.success()); | |
1351 | |
1352 AutofillEntry updated_entry(MakeAutofillEntry("my", "entry", 1, 2)); | |
1353 | |
1354 EXPECT_CALL(autofill_table(), GetAutofillTimestamps(_, _, _, _)) | |
1355 .WillOnce(DoAll(SetArgumentPointee<2>(updated_entry.date_created()), | |
1356 SetArgumentPointee<3>(updated_entry.date_last_used()), | |
1357 Return(true))); | |
1358 | |
1359 AutofillChangeList changes; | |
1360 changes.push_back(AutofillChange(AutofillChange::UPDATE, | |
1361 updated_entry.key())); | |
1362 web_data_service()->OnAutofillEntriesChanged(changes); | |
1363 | |
1364 std::vector<AutofillEntry> new_sync_entries; | |
1365 std::vector<AutofillProfile> new_sync_profiles; | |
1366 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries, | |
1367 &new_sync_profiles)); | |
1368 ASSERT_EQ(1U, new_sync_entries.size()); | |
1369 EXPECT_TRUE(updated_entry == new_sync_entries[0]); | |
1370 } | |
1371 | |
1372 | |
1373 TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeRemoveEntry) { | |
1374 AutofillEntry original_entry(MakeAutofillEntry("my", "entry", 1)); | |
1375 std::vector<AutofillEntry> original_entries; | |
1376 original_entries.push_back(original_entry); | |
1377 | |
1378 EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_)) | |
1379 .WillOnce(DoAll(SetArgumentPointee<0>(original_entries), Return(true))); | |
1380 EXPECT_CALL(personal_data_manager(), Refresh()); | |
1381 CreateRootHelper create_root(this, AUTOFILL); | |
1382 StartSyncService(create_root.callback(), false, AUTOFILL); | |
1383 ASSERT_TRUE(create_root.success()); | |
1384 | |
1385 AutofillChangeList changes; | |
1386 changes.push_back(AutofillChange(AutofillChange::REMOVE, | |
1387 original_entry.key())); | |
1388 web_data_service()->OnAutofillEntriesChanged(changes); | |
1389 | |
1390 std::vector<AutofillEntry> new_sync_entries; | |
1391 std::vector<AutofillProfile> new_sync_profiles; | |
1392 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries, | |
1393 &new_sync_profiles)); | |
1394 ASSERT_EQ(0U, new_sync_entries.size()); | |
1395 } | |
1396 | |
1397 TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeRemoveProfile) { | |
1398 AutofillProfile sync_profile; | |
1399 autofill::test::SetProfileInfoWithGuid(&sync_profile, | |
1400 "3BA5FA1B-1EC4-4BB3-9B57-EC92BE3C1A09", "Josephine", "Alicia", "Saenz", | |
1401 "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL", | |
1402 "32801", "US", "19482937549"); | |
1403 AutofillProfile* native_profile = new AutofillProfile; | |
1404 autofill::test::SetProfileInfoWithGuid(native_profile, | |
1405 "3BA5FA1B-1EC4-4BB3-9B57-EC92BE3C1A09", "Josephine", "Alicia", "Saenz", | |
1406 "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL", | |
1407 "32801", "US", "19482937549"); | |
1408 | |
1409 std::vector<AutofillProfile*> native_profiles; | |
1410 native_profiles.push_back(native_profile); | |
1411 EXPECT_CALL(autofill_table(), GetAutofillProfiles(_)) | |
1412 .WillOnce(DoAll(SetArgumentPointee<0>(native_profiles), Return(true))); | |
1413 | |
1414 std::vector<AutofillProfile> sync_profiles; | |
1415 sync_profiles.push_back(sync_profile); | |
1416 AddAutofillHelper<AutofillProfile> add_autofill(this, sync_profiles); | |
1417 EXPECT_CALL(personal_data_manager(), Refresh()); | |
1418 StartSyncService(add_autofill.callback(), false, AUTOFILL_PROFILE); | |
1419 ASSERT_TRUE(add_autofill.success()); | |
1420 | |
1421 AutofillProfileChange change( | |
1422 AutofillProfileChange::REMOVE, sync_profile.guid(), NULL); | |
1423 web_data_service()->OnAutofillProfileChanged(change); | |
1424 | |
1425 std::vector<AutofillProfile> new_sync_profiles; | |
1426 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode( | |
1427 &new_sync_profiles)); | |
1428 ASSERT_EQ(0U, new_sync_profiles.size()); | |
1429 } | |
1430 | |
1431 TEST_F(ProfileSyncServiceAutofillTest, ServerChangeRace) { | |
1432 // Once for MergeDataAndStartSyncing() and twice for ProcessSyncChanges(), via | |
1433 // LoadAutofillData(). | |
1434 EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_)) | |
1435 .Times(3) | |
1436 .WillRepeatedly(Return(true)); | |
1437 // On the other hand Autofill and Autocomplete are separated now, so | |
1438 // GetAutofillProfiles() should not be called. | |
1439 EXPECT_CALL(autofill_table(), GetAutofillProfiles(_)).Times(0); | |
1440 EXPECT_CALL(autofill_table(), UpdateAutofillEntries(_)) | |
1441 .WillRepeatedly(Return(true)); | |
1442 EXPECT_CALL(personal_data_manager(), Refresh()).Times(3); | |
1443 CreateRootHelper create_root(this, AUTOFILL); | |
1444 StartSyncService(create_root.callback(), false, AUTOFILL); | |
1445 ASSERT_TRUE(create_root.success()); | |
1446 | |
1447 std::unique_ptr<WaitableEvent> wait_for_start( | |
1448 new WaitableEvent(base::WaitableEvent::ResetPolicy::MANUAL, | |
1449 base::WaitableEvent::InitialState::NOT_SIGNALED)); | |
1450 std::unique_ptr<WaitableEvent> wait_for_syncapi( | |
1451 new WaitableEvent(base::WaitableEvent::ResetPolicy::MANUAL, | |
1452 base::WaitableEvent::InitialState::NOT_SIGNALED)); | |
1453 scoped_refptr<FakeServerUpdater> updater(new FakeServerUpdater( | |
1454 sync_service(), wait_for_start.get(), wait_for_syncapi.get(), | |
1455 data_type_thread()->task_runner())); | |
1456 | |
1457 // This server side update will stall waiting for CommitWaiter. | |
1458 updater->CreateNewEntry(MakeAutofillEntry("server", "entry", 1)); | |
1459 wait_for_start->Wait(); | |
1460 | |
1461 AutofillEntry syncapi_entry(MakeAutofillEntry("syncapi", "entry", 2)); | |
1462 ASSERT_TRUE(AddAutofillSyncNode(syncapi_entry)); | |
1463 DVLOG(1) << "Syncapi update finished."; | |
1464 | |
1465 // If we reach here, it means syncapi succeeded and we didn't deadlock. Yay! | |
1466 // Signal FakeServerUpdater that it can complete. | |
1467 wait_for_syncapi->Signal(); | |
1468 | |
1469 // Make another entry to ensure nothing broke afterwards and wait for finish | |
1470 // to clean up. | |
1471 updater->WaitForUpdateCompletion(); | |
1472 updater->CreateNewEntry(MakeAutofillEntry("server2", "entry2", 3)); | |
1473 updater->WaitForUpdateCompletion(); | |
1474 | |
1475 // Let callbacks posted on UI thread execute. | |
1476 base::RunLoop().RunUntilIdle(); | |
1477 | |
1478 std::vector<AutofillEntry> sync_entries; | |
1479 std::vector<AutofillProfile> sync_profiles; | |
1480 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles)); | |
1481 EXPECT_EQ(3U, sync_entries.size()); | |
1482 EXPECT_EQ(0U, sync_profiles.size()); | |
1483 for (size_t i = 0; i < sync_entries.size(); i++) { | |
1484 DVLOG(1) << "Entry " << i << ": " << sync_entries[i].key().name() | |
1485 << ", " << sync_entries[i].key().value(); | |
1486 } | |
1487 } | |
OLD | NEW |