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 <set>
6 #include <string>
7 #include <vector>
8
9 #include "testing/gtest/include/gtest/gtest.h"
10
11 #include "base/callback.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/message_loop.h"
15 #include "base/string16.h"
16 #include "base/synchronization/waitable_event.h"
17 #include "base/task.h"
18 #include "base/time.h"
19 #include "base/utf_string_conversions.h"
20 #include "chrome/browser/autofill/autofill_common_test.h"
21 #include "chrome/browser/sync/abstract_profile_sync_service_test.h"
22 #include "chrome/browser/sync/engine/model_changing_syncer_command.h"
23 #include "chrome/browser/sync/engine/syncapi.h"
24 #include "chrome/browser/sync/glue/autofill_change_processor.h"
25 #include "chrome/browser/sync/glue/autofill_data_type_controller.h"
26 #include "chrome/browser/sync/glue/autofill_model_associator.h"
27 #include "chrome/browser/sync/glue/autofill_profile_change_processor.h"
28 #include "chrome/browser/sync/glue/autofill_profile_data_type_controller.h"
29 #include "chrome/browser/sync/glue/autofill_profile_model_associator.h"
30 #include "chrome/browser/sync/glue/data_type_controller.h"
31 #include "chrome/browser/sync/profile_sync_factory.h"
32 #include "chrome/browser/sync/profile_sync_service.h"
33 #include "chrome/browser/sync/profile_sync_test_util.h"
34 #include "chrome/browser/sync/protocol/autofill_specifics.pb.h"
35 #include "chrome/browser/sync/syncable/autofill_migration.h"
36 #include "chrome/browser/sync/syncable/directory_manager.h"
37 #include "chrome/browser/sync/syncable/model_type.h"
38 #include "chrome/browser/sync/syncable/syncable.h"
39 #include "chrome/browser/sync/test_profile_sync_service.h"
40 #include "chrome/browser/webdata/autofill_change.h"
41 #include "chrome/browser/webdata/autofill_entry.h"
42 #include "chrome/browser/webdata/autofill_table.h"
43 #include "chrome/browser/webdata/web_database.h"
44 #include "chrome/common/net/gaia/gaia_constants.h"
45 #include "chrome/test/profile_mock.h"
46 #include "chrome/test/sync/engine/test_id_factory.h"
47 #include "content/browser/browser_thread.h"
48 #include "content/common/notification_source.h"
49 #include "content/common/notification_type.h"
50 #include "testing/gmock/include/gmock/gmock.h"
51
52 using base::Time;
53 using base::WaitableEvent;
54 using browser_sync::AutofillChangeProcessor;
55 using browser_sync::AutofillDataTypeController;
56 using browser_sync::AutofillModelAssociator;
57 using browser_sync::AutofillProfileChangeProcessor;
58 using browser_sync::AutofillProfileDataTypeController;
59 using browser_sync::AutofillProfileModelAssociator;
60 using browser_sync::DataTypeController;
61 using browser_sync::GROUP_DB;
62 using browser_sync::kAutofillTag;
63 using browser_sync::SyncBackendHostForProfileSyncTest;
64 using browser_sync::UnrecoverableErrorHandler;
65 using syncable::CREATE_NEW_UPDATE_ITEM;
66 using syncable::AUTOFILL;
67 using syncable::BASE_VERSION;
68 using syncable::CREATE;
69 using syncable::GET_BY_SERVER_TAG;
70 using syncable::INVALID;
71 using syncable::MutableEntry;
72 using syncable::OriginalEntries;
73 using syncable::SERVER_PARENT_ID;
74 using syncable::SERVER_SPECIFICS;
75 using syncable::SPECIFICS;
76 using syncable::UNITTEST;
77 using syncable::WriterTag;
78 using syncable::WriteTransaction;
79 using testing::_;
80 using testing::DoAll;
81 using testing::DoDefault;
82 using testing::ElementsAre;
83 using testing::Eq;
84 using testing::Invoke;
85 using testing::Mock;
86 using testing::Return;
87 using testing::SaveArg;
88 using testing::SetArgumentPointee;
89
90 namespace syncable {
91 class Id;
92 }
93
94 class AutofillTableMock : public AutofillTable {
95 public:
AutofillTableMock()96 AutofillTableMock() : AutofillTable(NULL, NULL) {}
97 MOCK_METHOD2(RemoveFormElement,
98 bool(const string16& name, const string16& value)); // NOLINT
99 MOCK_METHOD1(GetAllAutofillEntries,
100 bool(std::vector<AutofillEntry>* entries)); // NOLINT
101 MOCK_METHOD3(GetAutofillTimestamps,
102 bool(const string16& name, // NOLINT
103 const string16& value,
104 std::vector<base::Time>* timestamps));
105 MOCK_METHOD1(UpdateAutofillEntries,
106 bool(const std::vector<AutofillEntry>&)); // NOLINT
107 MOCK_METHOD1(GetAutofillProfiles,
108 bool(std::vector<AutofillProfile*>*)); // NOLINT
109 MOCK_METHOD1(UpdateAutofillProfile,
110 bool(const AutofillProfile&)); // NOLINT
111 MOCK_METHOD1(AddAutofillProfile,
112 bool(const AutofillProfile&)); // NOLINT
113 MOCK_METHOD1(RemoveAutofillProfile,
114 bool(const std::string&)); // NOLINT
115 };
116
117 class WebDatabaseFake : public WebDatabase {
118 public:
WebDatabaseFake(AutofillTable * autofill_table)119 explicit WebDatabaseFake(AutofillTable* autofill_table)
120 : autofill_table_(autofill_table) {}
121
GetAutofillTable()122 virtual AutofillTable* GetAutofillTable() {
123 return autofill_table_;
124 }
125
126 private:
127 AutofillTable* autofill_table_;
128 };
129
130
131 class ProfileSyncServiceAutofillTest;
132
133 template<class AutofillProfile>
GetModelType()134 syncable::ModelType GetModelType() {
135 return syncable::UNSPECIFIED;
136 }
137
138 template<>
GetModelType()139 syncable::ModelType GetModelType<AutofillEntry>() {
140 return syncable::AUTOFILL;
141 }
142
143 template<>
GetModelType()144 syncable::ModelType GetModelType<AutofillProfile>() {
145 return syncable::AUTOFILL_PROFILE;
146 }
147
148 class WebDataServiceFake : public WebDataService {
149 public:
WebDataServiceFake(WebDatabase * web_database)150 explicit WebDataServiceFake(WebDatabase* web_database)
151 : web_database_(web_database) {}
IsDatabaseLoaded()152 virtual bool IsDatabaseLoaded() {
153 return true;
154 }
155
GetDatabase()156 virtual WebDatabase* GetDatabase() {
157 return web_database_;
158 }
159
160 private:
161 WebDatabase* web_database_;
162 };
163
ACTION_P4(MakeAutofillSyncComponents,service,wd,pdm,dtc)164 ACTION_P4(MakeAutofillSyncComponents, service, wd, pdm, dtc) {
165 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB));
166 if (!BrowserThread::CurrentlyOn(BrowserThread::DB))
167 return ProfileSyncFactory::SyncComponents(NULL, NULL);
168 AutofillModelAssociator* model_associator =
169 new AutofillModelAssociator(service, wd, pdm);
170 AutofillChangeProcessor* change_processor =
171 new AutofillChangeProcessor(model_associator, wd, pdm, dtc);
172 return ProfileSyncFactory::SyncComponents(model_associator,
173 change_processor);
174 }
175
ACTION_P4(MakeAutofillProfileSyncComponents,service,wd,pdm,dtc)176 ACTION_P4(MakeAutofillProfileSyncComponents, service, wd, pdm, dtc) {
177 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB));
178 if (!BrowserThread::CurrentlyOn(BrowserThread::DB))
179 return ProfileSyncFactory::SyncComponents(NULL, NULL);
180 AutofillProfileModelAssociator* model_associator =
181 new AutofillProfileModelAssociator(service, wd, pdm);
182 AutofillProfileChangeProcessor* change_processor =
183 new AutofillProfileChangeProcessor(model_associator, wd, pdm, dtc);
184 return ProfileSyncFactory::SyncComponents(model_associator,
185 change_processor);
186 }
187
188 class AbstractAutofillFactory {
189 public:
190 virtual AutofillDataTypeController* CreateDataTypeController(
191 ProfileSyncFactory *factory,
192 ProfileMock* profile,
193 ProfileSyncService* service) = 0;
194 virtual void SetExpectation(ProfileSyncFactoryMock* factory,
195 ProfileSyncService* service,
196 WebDatabase* wd,
197 PersonalDataManager* pdm,
198 DataTypeController* dtc) = 0;
~AbstractAutofillFactory()199 virtual ~AbstractAutofillFactory() {}
200 };
201
202 class AutofillEntryFactory : public AbstractAutofillFactory {
203 public:
CreateDataTypeController(ProfileSyncFactory * factory,ProfileMock * profile,ProfileSyncService * service)204 browser_sync::AutofillDataTypeController* CreateDataTypeController(
205 ProfileSyncFactory *factory,
206 ProfileMock* profile,
207 ProfileSyncService* service) {
208 return new AutofillDataTypeController(factory,
209 profile,
210 service);
211 }
212
SetExpectation(ProfileSyncFactoryMock * factory,ProfileSyncService * service,WebDatabase * wd,PersonalDataManager * pdm,DataTypeController * dtc)213 void SetExpectation(ProfileSyncFactoryMock* factory,
214 ProfileSyncService* service,
215 WebDatabase* wd,
216 PersonalDataManager* pdm,
217 DataTypeController* dtc) {
218 EXPECT_CALL(*factory, CreateAutofillSyncComponents(_,_,_,_)).
219 WillOnce(MakeAutofillSyncComponents(service, wd, pdm, dtc));
220 }
221 };
222
223 class AutofillProfileFactory : public AbstractAutofillFactory {
224 public:
CreateDataTypeController(ProfileSyncFactory * factory,ProfileMock * profile,ProfileSyncService * service)225 browser_sync::AutofillDataTypeController* CreateDataTypeController(
226 ProfileSyncFactory *factory,
227 ProfileMock* profile,
228 ProfileSyncService* service) {
229 return new AutofillProfileDataTypeController(factory,
230 profile,
231 service);
232 }
233
SetExpectation(ProfileSyncFactoryMock * factory,ProfileSyncService * service,WebDatabase * wd,PersonalDataManager * pdm,DataTypeController * dtc)234 void SetExpectation(ProfileSyncFactoryMock* factory,
235 ProfileSyncService* service,
236 WebDatabase* wd,
237 PersonalDataManager* pdm,
238 DataTypeController* dtc) {
239 EXPECT_CALL(*factory, CreateAutofillProfileSyncComponents(_,_,_,_)).
240 WillOnce(MakeAutofillProfileSyncComponents(service, wd, pdm, dtc));
241 }
242 };
243
244 class PersonalDataManagerMock: public PersonalDataManager {
245 public:
246 MOCK_CONST_METHOD0(IsDataLoaded, bool());
247 MOCK_METHOD0(LoadProfiles, void());
248 MOCK_METHOD0(LoadCreditCards, void());
249 MOCK_METHOD0(Refresh, void());
250 };
251 template <class T> class AddAutofillTask;
252
253 class ProfileSyncServiceAutofillTest : public AbstractProfileSyncServiceTest {
254 protected:
ProfileSyncServiceAutofillTest()255 ProfileSyncServiceAutofillTest() : db_thread_(BrowserThread::DB) {}
256
257 AutofillProfileFactory profile_factory_;
258 AutofillEntryFactory entry_factory_;
259
GetFactory(syncable::ModelType type)260 AbstractAutofillFactory* GetFactory(syncable::ModelType type) {
261 if (type == syncable::AUTOFILL) {
262 return &entry_factory_;
263 } else if (type == syncable::AUTOFILL_PROFILE) {
264 return &profile_factory_;
265 } else {
266 NOTREACHED();
267 return NULL;
268 }
269 }
SetUp()270 virtual void SetUp() {
271 profile_.CreateRequestContext();
272 web_database_.reset(new WebDatabaseFake(&autofill_table_));
273 web_data_service_ = new WebDataServiceFake(web_database_.get());
274 personal_data_manager_ = new PersonalDataManagerMock();
275 EXPECT_CALL(*personal_data_manager_, LoadProfiles()).Times(1);
276 EXPECT_CALL(*personal_data_manager_, LoadCreditCards()).Times(1);
277 personal_data_manager_->Init(&profile_);
278 db_thread_.Start();
279
280 notification_service_ = new ThreadNotificationService(&db_thread_);
281 notification_service_->Init();
282 }
283
TearDown()284 virtual void TearDown() {
285 service_.reset();
286 notification_service_->TearDown();
287 db_thread_.Stop();
288 {
289 // The request context gets deleted on the I/O thread. To prevent a leak
290 // supply one here.
291 BrowserThread io_thread(BrowserThread::IO, MessageLoop::current());
292 profile_.ResetRequestContext();
293 }
294 MessageLoop::current()->RunAllPending();
295 }
296
StartSyncService(Task * task,bool will_fail_association,syncable::ModelType type)297 void StartSyncService(Task* task,
298 bool will_fail_association,
299 syncable::ModelType type) {
300 AbstractAutofillFactory* factory = GetFactory(type);
301 service_.reset(
302 new TestProfileSyncService(&factory_, &profile_, "test_user", false,
303 task));
304 AutofillDataTypeController* data_type_controller =
305 factory->CreateDataTypeController(&factory_,
306 &profile_,
307 service_.get());
308 SyncBackendHostForProfileSyncTest::
309 SetDefaultExpectationsForWorkerCreation(&profile_);
310
311 factory->SetExpectation(&factory_,
312 service_.get(),
313 web_database_.get(),
314 personal_data_manager_.get(),
315 data_type_controller);
316
317 EXPECT_CALL(factory_, CreateDataTypeManager(_, _)).
318 WillOnce(ReturnNewDataTypeManager());
319
320 EXPECT_CALL(profile_, GetWebDataService(_)).
321 WillOnce(Return(web_data_service_.get()));
322
323 EXPECT_CALL(profile_, GetPersonalDataManager()).
324 WillRepeatedly(Return(personal_data_manager_.get()));
325
326 EXPECT_CALL(*personal_data_manager_, IsDataLoaded()).
327 WillRepeatedly(Return(true));
328
329 // We need tokens to get the tests going
330 token_service_.IssueAuthTokenForTest(
331 GaiaConstants::kSyncService, "token");
332
333 EXPECT_CALL(profile_, GetTokenService()).
334 WillRepeatedly(Return(&token_service_));
335
336 service_->RegisterDataTypeController(data_type_controller);
337 service_->Initialize();
338 MessageLoop::current()->Run();
339 }
340
AddAutofillSyncNode(const AutofillEntry & entry)341 bool AddAutofillSyncNode(const AutofillEntry& entry) {
342 sync_api::WriteTransaction trans(service_->GetUserShare());
343 sync_api::ReadNode autofill_root(&trans);
344 if (!autofill_root.InitByTagLookup(browser_sync::kAutofillTag))
345 return false;
346
347 sync_api::WriteNode node(&trans);
348 std::string tag = AutofillModelAssociator::KeyToTag(entry.key().name(),
349 entry.key().value());
350 if (!node.InitUniqueByCreation(syncable::AUTOFILL, autofill_root, tag))
351 return false;
352
353 AutofillChangeProcessor::WriteAutofillEntry(entry, &node);
354 return true;
355 }
356
AddAutofillSyncNode(const AutofillProfile & profile)357 bool AddAutofillSyncNode(const AutofillProfile& profile) {
358 sync_api::WriteTransaction trans(service_->GetUserShare());
359 sync_api::ReadNode autofill_root(&trans);
360 if (!autofill_root.InitByTagLookup(browser_sync::kAutofillProfileTag))
361 return false;
362 sync_api::WriteNode node(&trans);
363 std::string tag = profile.guid();
364 if (!node.InitUniqueByCreation(syncable::AUTOFILL_PROFILE,
365 autofill_root, tag))
366 return false;
367 AutofillProfileChangeProcessor::WriteAutofillProfile(profile, &node);
368 return true;
369 }
370
GetAutofillEntriesFromSyncDB(std::vector<AutofillEntry> * entries,std::vector<AutofillProfile> * profiles)371 bool GetAutofillEntriesFromSyncDB(std::vector<AutofillEntry>* entries,
372 std::vector<AutofillProfile>* profiles) {
373 sync_api::ReadTransaction trans(service_->GetUserShare());
374 sync_api::ReadNode autofill_root(&trans);
375 if (!autofill_root.InitByTagLookup(browser_sync::kAutofillTag))
376 return false;
377
378 int64 child_id = autofill_root.GetFirstChildId();
379 while (child_id != sync_api::kInvalidId) {
380 sync_api::ReadNode child_node(&trans);
381 if (!child_node.InitByIdLookup(child_id))
382 return false;
383
384 const sync_pb::AutofillSpecifics& autofill(
385 child_node.GetAutofillSpecifics());
386 if (autofill.has_value()) {
387 AutofillKey key(UTF8ToUTF16(autofill.name()),
388 UTF8ToUTF16(autofill.value()));
389 std::vector<base::Time> timestamps;
390 int timestamps_count = autofill.usage_timestamp_size();
391 for (int i = 0; i < timestamps_count; ++i) {
392 timestamps.push_back(Time::FromInternalValue(
393 autofill.usage_timestamp(i)));
394 }
395 entries->push_back(AutofillEntry(key, timestamps));
396 } else if (autofill.has_profile()) {
397 AutofillProfile p;
398 p.set_guid(autofill.profile().guid());
399 AutofillProfileModelAssociator::OverwriteProfileWithServerData(&p,
400 autofill.profile());
401 profiles->push_back(p);
402 }
403 child_id = child_node.GetSuccessorId();
404 }
405 return true;
406 }
407
GetAutofillProfilesFromSyncDBUnderProfileNode(std::vector<AutofillProfile> * profiles)408 bool GetAutofillProfilesFromSyncDBUnderProfileNode(
409 std::vector<AutofillProfile>* profiles) {
410 sync_api::ReadTransaction trans(service_->GetUserShare());
411 sync_api::ReadNode autofill_root(&trans);
412 if (!autofill_root.InitByTagLookup(browser_sync::kAutofillProfileTag))
413 return false;
414
415 int64 child_id = autofill_root.GetFirstChildId();
416 while (child_id != sync_api::kInvalidId) {
417 sync_api::ReadNode child_node(&trans);
418 if (!child_node.InitByIdLookup(child_id))
419 return false;
420
421 const sync_pb::AutofillProfileSpecifics& autofill(
422 child_node.GetAutofillProfileSpecifics());
423 AutofillProfile p;
424 p.set_guid(autofill.guid());
425 AutofillProfileModelAssociator::OverwriteProfileWithServerData(&p,
426 autofill);
427 profiles->push_back(p);
428 child_id = child_node.GetSuccessorId();
429 }
430 return true;
431 }
432
SetIdleChangeProcessorExpectations()433 void SetIdleChangeProcessorExpectations() {
434 EXPECT_CALL(autofill_table_, RemoveFormElement(_, _)).Times(0);
435 EXPECT_CALL(autofill_table_, GetAutofillTimestamps(_, _, _)).Times(0);
436 EXPECT_CALL(autofill_table_, UpdateAutofillEntries(_)).Times(0);
437 }
438
MakeAutofillEntry(const char * name,const char * value,time_t timestamp0,time_t timestamp1)439 static AutofillEntry MakeAutofillEntry(const char* name,
440 const char* value,
441 time_t timestamp0,
442 time_t timestamp1) {
443 std::vector<Time> timestamps;
444 if (timestamp0 > 0)
445 timestamps.push_back(Time::FromTimeT(timestamp0));
446 if (timestamp1 > 0)
447 timestamps.push_back(Time::FromTimeT(timestamp1));
448 return AutofillEntry(
449 AutofillKey(ASCIIToUTF16(name), ASCIIToUTF16(value)), timestamps);
450 }
451
MakeAutofillEntry(const char * name,const char * value,time_t timestamp)452 static AutofillEntry MakeAutofillEntry(const char* name,
453 const char* value,
454 time_t timestamp) {
455 return MakeAutofillEntry(name, value, timestamp, -1);
456 }
457
458 friend class AddAutofillTask<AutofillEntry>;
459 friend class AddAutofillTask<AutofillProfile>;
460 friend class FakeServerUpdater;
461
462 BrowserThread db_thread_;
463 scoped_refptr<ThreadNotificationService> notification_service_;
464
465 ProfileMock profile_;
466 AutofillTableMock autofill_table_;
467 scoped_ptr<WebDatabaseFake> web_database_;
468 scoped_refptr<WebDataService> web_data_service_;
469 scoped_refptr<PersonalDataManagerMock> personal_data_manager_;
470 };
471
472 template <class T>
473 class AddAutofillTask : public Task {
474 public:
AddAutofillTask(ProfileSyncServiceAutofillTest * test,const std::vector<T> & entries)475 AddAutofillTask(ProfileSyncServiceAutofillTest* test,
476 const std::vector<T>& entries)
477 : test_(test), entries_(entries), success_(false) {
478 }
479
Run()480 virtual void Run() {
481 if (!test_->CreateRoot(GetModelType<T>()))
482 return;
483 for (size_t i = 0; i < entries_.size(); ++i) {
484 if (!test_->AddAutofillSyncNode(entries_[i]))
485 return;
486 }
487 success_ = true;
488 }
success()489 bool success() { return success_; }
490
491 private:
492 ProfileSyncServiceAutofillTest* test_;
493 const std::vector<T>& entries_;
494 bool success_;
495 };
496
497 // Overload write transaction to use custom NotifyTransactionComplete
498 static const bool kLoggingInfo = true;
499 class WriteTransactionTest: public WriteTransaction {
500 public:
WriteTransactionTest(const syncable::ScopedDirLookup & directory,WriterTag writer,const char * source_file,int line,scoped_ptr<WaitableEvent> * wait_for_syncapi)501 WriteTransactionTest(const syncable::ScopedDirLookup& directory,
502 WriterTag writer, const char* source_file,
503 int line,
504 scoped_ptr<WaitableEvent> *wait_for_syncapi)
505 : WriteTransaction(directory, writer, source_file, line),
506 wait_for_syncapi_(wait_for_syncapi) { }
507
NotifyTransactionComplete(syncable::ModelTypeBitSet types)508 virtual void NotifyTransactionComplete(syncable::ModelTypeBitSet types) {
509 // This is where we differ. Force a thread change here, giving another
510 // thread a chance to create a WriteTransaction
511 (*wait_for_syncapi_)->Wait();
512
513 WriteTransaction::NotifyTransactionComplete(types);
514 }
515
516 private:
517 scoped_ptr<WaitableEvent> *wait_for_syncapi_;
518 };
519
520 // Our fake server updater. Needs the RefCountedThreadSafe inheritance so we can
521 // post tasks with it.
522 class FakeServerUpdater: public base::RefCountedThreadSafe<FakeServerUpdater> {
523 public:
FakeServerUpdater(TestProfileSyncService * service,scoped_ptr<WaitableEvent> * wait_for_start,scoped_ptr<WaitableEvent> * wait_for_syncapi)524 FakeServerUpdater(TestProfileSyncService *service,
525 scoped_ptr<WaitableEvent> *wait_for_start,
526 scoped_ptr<WaitableEvent> *wait_for_syncapi)
527 : entry_(ProfileSyncServiceAutofillTest::MakeAutofillEntry("0", "0", 0)),
528 service_(service),
529 wait_for_start_(wait_for_start),
530 wait_for_syncapi_(wait_for_syncapi),
531 is_finished_(false, false) { }
532
Update()533 void Update() {
534 // This gets called in a modelsafeworker thread.
535 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB));
536
537 sync_api::UserShare* user_share = service_->GetUserShare();
538 syncable::DirectoryManager* dir_manager = user_share->dir_manager.get();
539 syncable::ScopedDirLookup dir(dir_manager, user_share->name);
540 ASSERT_TRUE(dir.good());
541
542 // Create autofill protobuf
543 std::string tag = AutofillModelAssociator::KeyToTag(entry_.key().name(),
544 entry_.key().value());
545 sync_pb::AutofillSpecifics new_autofill;
546 new_autofill.set_name(UTF16ToUTF8(entry_.key().name()));
547 new_autofill.set_value(UTF16ToUTF8(entry_.key().value()));
548 const std::vector<base::Time>& ts(entry_.timestamps());
549 for (std::vector<base::Time>::const_iterator timestamp = ts.begin();
550 timestamp != ts.end(); ++timestamp) {
551 new_autofill.add_usage_timestamp(timestamp->ToInternalValue());
552 }
553
554 sync_pb::EntitySpecifics entity_specifics;
555 entity_specifics.MutableExtension(sync_pb::autofill)->
556 CopyFrom(new_autofill);
557
558 {
559 // Tell main thread we've started
560 (*wait_for_start_)->Signal();
561
562 // Create write transaction.
563 WriteTransactionTest trans(dir, UNITTEST, __FILE__, __LINE__,
564 wait_for_syncapi_);
565
566 // Create actual entry based on autofill protobuf information.
567 // Simulates effects of SyncerUtil::UpdateLocalDataFromServerData
568 MutableEntry parent(&trans, GET_BY_SERVER_TAG, kAutofillTag);
569 MutableEntry item(&trans, CREATE, parent.Get(syncable::ID), tag);
570 ASSERT_TRUE(item.good());
571 item.Put(SPECIFICS, entity_specifics);
572 item.Put(SERVER_SPECIFICS, entity_specifics);
573 item.Put(BASE_VERSION, 1);
574 syncable::Id server_item_id = service_->id_factory()->NewServerId();
575 item.Put(syncable::ID, server_item_id);
576 syncable::Id new_predecessor;
577 ASSERT_TRUE(item.PutPredecessor(new_predecessor));
578 }
579 VLOG(1) << "FakeServerUpdater finishing.";
580 is_finished_.Signal();
581 }
582
CreateNewEntry(const AutofillEntry & entry)583 void CreateNewEntry(const AutofillEntry& entry) {
584 entry_ = entry;
585 scoped_ptr<Callback0::Type> c(NewCallback((FakeServerUpdater *)this,
586 &FakeServerUpdater::Update));
587 std::vector<browser_sync::ModelSafeWorker*> workers;
588 service_->GetBackendForTest()->GetWorkers(&workers);
589
590 ASSERT_FALSE(BrowserThread::CurrentlyOn(BrowserThread::DB));
591 if (!BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
592 NewRunnableMethod(this, &FakeServerUpdater::Update))) {
593 NOTREACHED() << "Failed to post task to the db thread.";
594 return;
595 }
596 }
597
CreateNewEntryAndWait(const AutofillEntry & entry)598 void CreateNewEntryAndWait(const AutofillEntry& entry) {
599 entry_ = entry;
600 scoped_ptr<Callback0::Type> c(NewCallback((FakeServerUpdater *)this,
601 &FakeServerUpdater::Update));
602 std::vector<browser_sync::ModelSafeWorker*> workers;
603 service_->GetBackendForTest()->GetWorkers(&workers);
604
605 ASSERT_FALSE(BrowserThread::CurrentlyOn(BrowserThread::DB));
606 is_finished_.Reset();
607 if (!BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
608 NewRunnableMethod(this, &FakeServerUpdater::Update))) {
609 NOTREACHED() << "Failed to post task to the db thread.";
610 return;
611 }
612 is_finished_.Wait();
613 }
614
615 private:
616 friend class base::RefCountedThreadSafe<FakeServerUpdater>;
~FakeServerUpdater()617 ~FakeServerUpdater() { }
618
619 AutofillEntry entry_;
620 TestProfileSyncService *service_;
621 scoped_ptr<WaitableEvent> *wait_for_start_;
622 scoped_ptr<WaitableEvent> *wait_for_syncapi_;
623 WaitableEvent is_finished_;
624 syncable::Id parent_id_;
625 };
626
627 // TODO(skrul): Test abort startup.
628 // TODO(skrul): Test processing of cloud changes.
629 // TODO(tim): Add autofill data type controller test, and a case to cover
630 // waiting for the PersonalDataManager.
TEST_F(ProfileSyncServiceAutofillTest,FailModelAssociation)631 TEST_F(ProfileSyncServiceAutofillTest, FailModelAssociation) {
632 // Don't create the root autofill node so startup fails.
633 StartSyncService(NULL, true, syncable::AUTOFILL);
634 EXPECT_TRUE(service_->unrecoverable_error_detected());
635 }
636
TEST_F(ProfileSyncServiceAutofillTest,EmptyNativeEmptySync)637 TEST_F(ProfileSyncServiceAutofillTest, EmptyNativeEmptySync) {
638 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).WillOnce(Return(true));
639 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).WillOnce(Return(true));
640 SetIdleChangeProcessorExpectations();
641 CreateRootTask task(this, syncable::AUTOFILL);
642 EXPECT_CALL(*personal_data_manager_, Refresh());
643 StartSyncService(&task, false, syncable::AUTOFILL);
644 ASSERT_TRUE(task.success());
645 std::vector<AutofillEntry> sync_entries;
646 std::vector<AutofillProfile> sync_profiles;
647 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles));
648 EXPECT_EQ(0U, sync_entries.size());
649 EXPECT_EQ(0U, sync_profiles.size());
650 }
651
TEST_F(ProfileSyncServiceAutofillTest,HasNativeEntriesEmptySync)652 TEST_F(ProfileSyncServiceAutofillTest, HasNativeEntriesEmptySync) {
653 std::vector<AutofillEntry> entries;
654 entries.push_back(MakeAutofillEntry("foo", "bar", 1));
655 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).
656 WillOnce(DoAll(SetArgumentPointee<0>(entries), Return(true)));
657 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).WillOnce(Return(true));
658 SetIdleChangeProcessorExpectations();
659 CreateRootTask task(this, syncable::AUTOFILL);
660 EXPECT_CALL(*personal_data_manager_, Refresh());
661 StartSyncService(&task, false, syncable::AUTOFILL);
662 ASSERT_TRUE(task.success());
663 std::vector<AutofillEntry> sync_entries;
664 std::vector<AutofillProfile> sync_profiles;
665 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles));
666 ASSERT_EQ(1U, entries.size());
667 EXPECT_TRUE(entries[0] == sync_entries[0]);
668 EXPECT_EQ(0U, sync_profiles.size());
669 }
670
TEST_F(ProfileSyncServiceAutofillTest,HasProfileEmptySync)671 TEST_F(ProfileSyncServiceAutofillTest, HasProfileEmptySync) {
672
673 std::vector<AutofillProfile*> profiles;
674 std::vector<AutofillProfile> expected_profiles;
675 // Owned by GetAutofillProfiles caller.
676 AutofillProfile* profile0 = new AutofillProfile;
677 autofill_test::SetProfileInfoWithGuid(profile0,
678 "54B3F9AA-335E-4F71-A27D-719C41564230", "Billing",
679 "Mitchell", "Morrison",
680 "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
681 "91601", "US", "12345678910", "01987654321");
682 profiles.push_back(profile0);
683 expected_profiles.push_back(*profile0);
684 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).
685 WillOnce(DoAll(SetArgumentPointee<0>(profiles), Return(true)));
686 EXPECT_CALL(*personal_data_manager_, Refresh());
687 SetIdleChangeProcessorExpectations();
688 CreateRootTask task(this, syncable::AUTOFILL_PROFILE);
689 StartSyncService(&task, false, syncable::AUTOFILL_PROFILE);
690 ASSERT_TRUE(task.success());
691 std::vector<AutofillProfile> sync_profiles;
692 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(&sync_profiles));
693 EXPECT_EQ(1U, sync_profiles.size());
694 EXPECT_EQ(0, expected_profiles[0].Compare(sync_profiles[0]));
695 }
696
TEST_F(ProfileSyncServiceAutofillTest,HasNativeWithDuplicatesEmptySync)697 TEST_F(ProfileSyncServiceAutofillTest, HasNativeWithDuplicatesEmptySync) {
698 // There is buggy autofill code that allows duplicate name/value
699 // pairs to exist in the database with separate pair_ids.
700 std::vector<AutofillEntry> entries;
701 entries.push_back(MakeAutofillEntry("foo", "bar", 1));
702 entries.push_back(MakeAutofillEntry("dup", "", 2));
703 entries.push_back(MakeAutofillEntry("dup", "", 3));
704 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).
705 WillOnce(DoAll(SetArgumentPointee<0>(entries), Return(true)));
706 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).WillOnce(Return(true));
707 SetIdleChangeProcessorExpectations();
708 CreateRootTask task(this, syncable::AUTOFILL);
709 EXPECT_CALL(*personal_data_manager_, Refresh());
710 StartSyncService(&task, false, syncable::AUTOFILL);
711 ASSERT_TRUE(task.success());
712 std::vector<AutofillEntry> sync_entries;
713 std::vector<AutofillProfile> sync_profiles;
714 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles));
715 EXPECT_EQ(2U, sync_entries.size());
716 }
717
TEST_F(ProfileSyncServiceAutofillTest,HasNativeHasSyncNoMerge)718 TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncNoMerge) {
719 AutofillEntry native_entry(MakeAutofillEntry("native", "entry", 1));
720 AutofillEntry sync_entry(MakeAutofillEntry("sync", "entry", 2));
721
722 std::vector<AutofillEntry> native_entries;
723 native_entries.push_back(native_entry);
724
725 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).
726 WillOnce(DoAll(SetArgumentPointee<0>(native_entries), Return(true)));
727
728 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).WillOnce(Return(true));
729
730 std::vector<AutofillEntry> sync_entries;
731 sync_entries.push_back(sync_entry);
732
733 AddAutofillTask<AutofillEntry> task(this, sync_entries);
734
735 EXPECT_CALL(autofill_table_, UpdateAutofillEntries(ElementsAre(sync_entry))).
736 WillOnce(Return(true));
737
738 EXPECT_CALL(*personal_data_manager_, Refresh());
739 StartSyncService(&task, false, syncable::AUTOFILL);
740 ASSERT_TRUE(task.success());
741
742 std::set<AutofillEntry> expected_entries;
743 expected_entries.insert(native_entry);
744 expected_entries.insert(sync_entry);
745
746 std::vector<AutofillEntry> new_sync_entries;
747 std::vector<AutofillProfile> new_sync_profiles;
748 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries,
749 &new_sync_profiles));
750 std::set<AutofillEntry> new_sync_entries_set(new_sync_entries.begin(),
751 new_sync_entries.end());
752
753 EXPECT_TRUE(expected_entries == new_sync_entries_set);
754 }
755
TEST_F(ProfileSyncServiceAutofillTest,HasNativeHasSyncMergeEntry)756 TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncMergeEntry) {
757 AutofillEntry native_entry(MakeAutofillEntry("merge", "entry", 1));
758 AutofillEntry sync_entry(MakeAutofillEntry("merge", "entry", 2));
759 AutofillEntry merged_entry(MakeAutofillEntry("merge", "entry", 1, 2));
760
761 std::vector<AutofillEntry> native_entries;
762 native_entries.push_back(native_entry);
763 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).
764 WillOnce(DoAll(SetArgumentPointee<0>(native_entries), Return(true)));
765 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).WillOnce(Return(true));
766
767 std::vector<AutofillEntry> sync_entries;
768 sync_entries.push_back(sync_entry);
769 AddAutofillTask<AutofillEntry> task(this, sync_entries);
770
771 EXPECT_CALL(autofill_table_,
772 UpdateAutofillEntries(ElementsAre(merged_entry))).WillOnce(Return(true));
773 EXPECT_CALL(*personal_data_manager_, Refresh());
774 StartSyncService(&task, false, syncable::AUTOFILL);
775 ASSERT_TRUE(task.success());
776
777 std::vector<AutofillEntry> new_sync_entries;
778 std::vector<AutofillProfile> new_sync_profiles;
779 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries,
780 &new_sync_profiles));
781 ASSERT_EQ(1U, new_sync_entries.size());
782 EXPECT_TRUE(merged_entry == new_sync_entries[0]);
783 }
784
TEST_F(ProfileSyncServiceAutofillTest,HasNativeHasSyncMergeProfile)785 TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncMergeProfile) {
786 AutofillProfile sync_profile;
787 autofill_test::SetProfileInfoWithGuid(&sync_profile,
788 "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing",
789 "Mitchell", "Morrison",
790 "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
791 "91601", "US", "12345678910", "01987654321");
792
793 AutofillProfile* native_profile = new AutofillProfile;
794 autofill_test::SetProfileInfoWithGuid(native_profile,
795 "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing", "Alicia", "Saenz",
796 "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
797 "32801", "US", "19482937549", "13502849239");
798
799 std::vector<AutofillProfile*> native_profiles;
800 native_profiles.push_back(native_profile);
801 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).
802 WillOnce(DoAll(SetArgumentPointee<0>(native_profiles), Return(true)));
803
804 std::vector<AutofillProfile> sync_profiles;
805 sync_profiles.push_back(sync_profile);
806 AddAutofillTask<AutofillProfile> task(this, sync_profiles);
807
808 EXPECT_CALL(autofill_table_, UpdateAutofillProfile(_)).
809 WillOnce(Return(true));
810 EXPECT_CALL(*personal_data_manager_, Refresh());
811 StartSyncService(&task, false, syncable::AUTOFILL_PROFILE);
812 ASSERT_TRUE(task.success());
813
814 std::vector<AutofillProfile> new_sync_profiles;
815 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(
816 &new_sync_profiles));
817 ASSERT_EQ(1U, new_sync_profiles.size());
818 EXPECT_EQ(0, sync_profile.Compare(new_sync_profiles[0]));
819 }
820
TEST_F(ProfileSyncServiceAutofillTest,MergeProfileWithDifferentGuid)821 TEST_F(ProfileSyncServiceAutofillTest, MergeProfileWithDifferentGuid) {
822 AutofillProfile sync_profile;
823
824 autofill_test::SetProfileInfoWithGuid(&sync_profile,
825 "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing",
826 "Mitchell", "Morrison",
827 "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
828 "91601", "US", "12345678910", "01987654321");
829
830 std::string native_guid = "EDC609ED-7EEE-4F27-B00C-423242A9C44B";
831 AutofillProfile* native_profile = new AutofillProfile;
832 autofill_test::SetProfileInfoWithGuid(native_profile,
833 native_guid.c_str(), "Billing",
834 "Mitchell", "Morrison",
835 "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
836 "91601", "US", "12345678910", "01987654321");
837
838 std::vector<AutofillProfile*> native_profiles;
839 native_profiles.push_back(native_profile);
840 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).
841 WillOnce(DoAll(SetArgumentPointee<0>(native_profiles), Return(true)));
842
843 std::vector<AutofillProfile> sync_profiles;
844 sync_profiles.push_back(sync_profile);
845 AddAutofillTask<AutofillProfile> task(this, sync_profiles);
846
847 EXPECT_CALL(autofill_table_, AddAutofillProfile(_)).
848 WillOnce(Return(true));
849 EXPECT_CALL(autofill_table_, RemoveAutofillProfile(native_guid)).
850 WillOnce(Return(true));
851 EXPECT_CALL(*personal_data_manager_, Refresh());
852 StartSyncService(&task, false, syncable::AUTOFILL_PROFILE);
853 ASSERT_TRUE(task.success());
854
855 std::vector<AutofillProfile> new_sync_profiles;
856 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(
857 &new_sync_profiles));
858 ASSERT_EQ(1U, new_sync_profiles.size());
859 EXPECT_EQ(0, sync_profile.Compare(new_sync_profiles[0]));
860 EXPECT_EQ(sync_profile.guid(), new_sync_profiles[0].guid());
861 }
862
TEST_F(ProfileSyncServiceAutofillTest,ProcessUserChangeAddEntry)863 TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeAddEntry) {
864 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).WillOnce(Return(true));
865 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).WillOnce(Return(true));
866 EXPECT_CALL(*personal_data_manager_, Refresh());
867 SetIdleChangeProcessorExpectations();
868 CreateRootTask task(this, syncable::AUTOFILL);
869 StartSyncService(&task, false, syncable::AUTOFILL);
870 ASSERT_TRUE(task.success());
871
872 AutofillEntry added_entry(MakeAutofillEntry("added", "entry", 1));
873 std::vector<base::Time> timestamps(added_entry.timestamps());
874
875 EXPECT_CALL(autofill_table_, GetAutofillTimestamps(_, _, _)).
876 WillOnce(DoAll(SetArgumentPointee<2>(timestamps), Return(true)));
877
878 AutofillChangeList changes;
879 changes.push_back(AutofillChange(AutofillChange::ADD, added_entry.key()));
880 scoped_refptr<ThreadNotifier> notifier(new ThreadNotifier(&db_thread_));
881 notifier->Notify(NotificationType::AUTOFILL_ENTRIES_CHANGED,
882 Source<WebDataService>(web_data_service_.get()),
883 Details<AutofillChangeList>(&changes));
884
885 std::vector<AutofillEntry> new_sync_entries;
886 std::vector<AutofillProfile> new_sync_profiles;
887 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries,
888 &new_sync_profiles));
889 ASSERT_EQ(1U, new_sync_entries.size());
890 EXPECT_TRUE(added_entry == new_sync_entries[0]);
891 }
892
TEST_F(ProfileSyncServiceAutofillTest,ProcessUserChangeAddProfile)893 TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeAddProfile) {
894 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).WillOnce(Return(true));
895 EXPECT_CALL(*personal_data_manager_, Refresh());
896 SetIdleChangeProcessorExpectations();
897 CreateRootTask task(this, syncable::AUTOFILL_PROFILE);
898 StartSyncService(&task, false, syncable::AUTOFILL_PROFILE);
899 ASSERT_TRUE(task.success());
900
901 AutofillProfile added_profile;
902 autofill_test::SetProfileInfoWithGuid(&added_profile,
903 "D6ADA912-D374-4C0A-917D-F5C8EBE43011", "Josephine", "Alicia", "Saenz",
904 "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
905 "32801", "US", "19482937549", "13502849239");
906
907 AutofillProfileChange change(AutofillProfileChange::ADD,
908 added_profile.guid(), &added_profile);
909 scoped_refptr<ThreadNotifier> notifier(new ThreadNotifier(&db_thread_));
910 notifier->Notify(NotificationType::AUTOFILL_PROFILE_CHANGED,
911 Source<WebDataService>(web_data_service_.get()),
912 Details<AutofillProfileChange>(&change));
913
914 std::vector<AutofillProfile> new_sync_profiles;
915 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(
916 &new_sync_profiles));
917 ASSERT_EQ(1U, new_sync_profiles.size());
918 EXPECT_EQ(0, added_profile.Compare(new_sync_profiles[0]));
919 }
920
TEST_F(ProfileSyncServiceAutofillTest,ProcessUserChangeUpdateEntry)921 TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeUpdateEntry) {
922 AutofillEntry original_entry(MakeAutofillEntry("my", "entry", 1));
923 std::vector<AutofillEntry> original_entries;
924 original_entries.push_back(original_entry);
925
926 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).
927 WillOnce(DoAll(SetArgumentPointee<0>(original_entries), Return(true)));
928 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).WillOnce(Return(true));
929 EXPECT_CALL(*personal_data_manager_, Refresh());
930 CreateRootTask task(this, syncable::AUTOFILL);
931 StartSyncService(&task, false, syncable::AUTOFILL);
932 ASSERT_TRUE(task.success());
933
934 AutofillEntry updated_entry(MakeAutofillEntry("my", "entry", 1, 2));
935 std::vector<base::Time> timestamps(updated_entry.timestamps());
936
937 EXPECT_CALL(autofill_table_, GetAutofillTimestamps(_, _, _)).
938 WillOnce(DoAll(SetArgumentPointee<2>(timestamps), Return(true)));
939
940 AutofillChangeList changes;
941 changes.push_back(AutofillChange(AutofillChange::UPDATE,
942 updated_entry.key()));
943 scoped_refptr<ThreadNotifier> notifier(new ThreadNotifier(&db_thread_));
944 notifier->Notify(NotificationType::AUTOFILL_ENTRIES_CHANGED,
945 Source<WebDataService>(web_data_service_.get()),
946 Details<AutofillChangeList>(&changes));
947
948 std::vector<AutofillEntry> new_sync_entries;
949 std::vector<AutofillProfile> new_sync_profiles;
950 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries,
951 &new_sync_profiles));
952 ASSERT_EQ(1U, new_sync_entries.size());
953 EXPECT_TRUE(updated_entry == new_sync_entries[0]);
954 }
955
956
TEST_F(ProfileSyncServiceAutofillTest,ProcessUserChangeRemoveEntry)957 TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeRemoveEntry) {
958 AutofillEntry original_entry(MakeAutofillEntry("my", "entry", 1));
959 std::vector<AutofillEntry> original_entries;
960 original_entries.push_back(original_entry);
961
962 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).
963 WillOnce(DoAll(SetArgumentPointee<0>(original_entries), Return(true)));
964 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).WillOnce(Return(true));
965 EXPECT_CALL(*personal_data_manager_, Refresh());
966 CreateRootTask task(this, syncable::AUTOFILL);
967 StartSyncService(&task, false, syncable::AUTOFILL);
968 ASSERT_TRUE(task.success());
969
970 AutofillChangeList changes;
971 changes.push_back(AutofillChange(AutofillChange::REMOVE,
972 original_entry.key()));
973 scoped_refptr<ThreadNotifier> notifier(new ThreadNotifier(&db_thread_));
974 notifier->Notify(NotificationType::AUTOFILL_ENTRIES_CHANGED,
975 Source<WebDataService>(web_data_service_.get()),
976 Details<AutofillChangeList>(&changes));
977
978 std::vector<AutofillEntry> new_sync_entries;
979 std::vector<AutofillProfile> new_sync_profiles;
980 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries,
981 &new_sync_profiles));
982 ASSERT_EQ(0U, new_sync_entries.size());
983 }
984
TEST_F(ProfileSyncServiceAutofillTest,ProcessUserChangeRemoveProfile)985 TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeRemoveProfile) {
986 AutofillProfile sync_profile;
987 autofill_test::SetProfileInfoWithGuid(&sync_profile,
988 "3BA5FA1B-1EC4-4BB3-9B57-EC92BE3C1A09", "Josephine", "Alicia", "Saenz",
989 "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
990 "32801", "US", "19482937549", "13502849239");
991 AutofillProfile* native_profile = new AutofillProfile;
992 autofill_test::SetProfileInfoWithGuid(native_profile,
993 "3BA5FA1B-1EC4-4BB3-9B57-EC92BE3C1A09", "Josephine", "Alicia", "Saenz",
994 "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
995 "32801", "US", "19482937549", "13502849239");
996
997 std::vector<AutofillProfile*> native_profiles;
998 native_profiles.push_back(native_profile);
999 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).
1000 WillOnce(DoAll(SetArgumentPointee<0>(native_profiles), Return(true)));
1001
1002 std::vector<AutofillProfile> sync_profiles;
1003 sync_profiles.push_back(sync_profile);
1004 AddAutofillTask<AutofillProfile> task(this, sync_profiles);
1005 EXPECT_CALL(*personal_data_manager_, Refresh());
1006 StartSyncService(&task, false, syncable::AUTOFILL_PROFILE);
1007 ASSERT_TRUE(task.success());
1008
1009 AutofillProfileChange change(AutofillProfileChange::REMOVE,
1010 sync_profile.guid(), NULL);
1011 scoped_refptr<ThreadNotifier> notifier(new ThreadNotifier(&db_thread_));
1012 notifier->Notify(NotificationType::AUTOFILL_PROFILE_CHANGED,
1013 Source<WebDataService>(web_data_service_.get()),
1014 Details<AutofillProfileChange>(&change));
1015
1016 std::vector<AutofillProfile> new_sync_profiles;
1017 ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(
1018 &new_sync_profiles));
1019 ASSERT_EQ(0U, new_sync_profiles.size());
1020 }
1021
TEST_F(ProfileSyncServiceAutofillTest,ProcessUserChangeError)1022 TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeError) {
1023 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).WillOnce(Return(true));
1024 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).WillOnce(Return(true));
1025 EXPECT_CALL(*personal_data_manager_, Refresh());
1026 CreateRootTask task(this, syncable::AUTOFILL);
1027 StartSyncService(&task, false, syncable::AUTOFILL);
1028 ASSERT_TRUE(task.success());
1029
1030 // Inject an evil entry into the sync db to conflict with the same
1031 // entry added by the user.
1032 AutofillEntry evil_entry(MakeAutofillEntry("evil", "entry", 1));
1033 ASSERT_TRUE(AddAutofillSyncNode(evil_entry));
1034
1035 AutofillChangeList changes;
1036 changes.push_back(AutofillChange(AutofillChange::ADD,
1037 evil_entry.key()));
1038 scoped_refptr<ThreadNotifier> notifier(new ThreadNotifier(&db_thread_));
1039 notifier->Notify(NotificationType::AUTOFILL_ENTRIES_CHANGED,
1040 Source<WebDataService>(web_data_service_.get()),
1041 Details<AutofillChangeList>(&changes));
1042
1043 // Wait for the PPS to shut everything down and signal us.
1044 ProfileSyncServiceObserverMock observer;
1045 service_->AddObserver(&observer);
1046 EXPECT_CALL(observer, OnStateChanged()).WillOnce(QuitUIMessageLoop());
1047 MessageLoop::current()->Run();
1048 EXPECT_TRUE(service_->unrecoverable_error_detected());
1049
1050 // Ensure future autofill notifications don't crash.
1051 notifier->Notify(NotificationType::AUTOFILL_ENTRIES_CHANGED,
1052 Source<WebDataService>(web_data_service_.get()),
1053 Details<AutofillChangeList>(&changes));
1054 }
1055
1056 // Crashy, http://crbug.com/57884
TEST_F(ProfileSyncServiceAutofillTest,DISABLED_ServerChangeRace)1057 TEST_F(ProfileSyncServiceAutofillTest, DISABLED_ServerChangeRace) {
1058 EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).WillOnce(Return(true));
1059 EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).WillOnce(Return(true));
1060 EXPECT_CALL(autofill_table_, UpdateAutofillEntries(_)).
1061 WillRepeatedly(Return(true));
1062 EXPECT_CALL(*personal_data_manager_, Refresh()).Times(3);
1063 CreateRootTask task(this, syncable::AUTOFILL);
1064 StartSyncService(&task, false, syncable::AUTOFILL);
1065 ASSERT_TRUE(task.success());
1066
1067 // (true, false) means we have to reset after |Signal|, init to unsignaled.
1068 scoped_ptr<WaitableEvent> wait_for_start(new WaitableEvent(true, false));
1069 scoped_ptr<WaitableEvent> wait_for_syncapi(new WaitableEvent(true, false));
1070 scoped_refptr<FakeServerUpdater> updater(new FakeServerUpdater(
1071 service_.get(), &wait_for_start, &wait_for_syncapi));
1072
1073 // This server side update will stall waiting for CommitWaiter.
1074 updater->CreateNewEntry(MakeAutofillEntry("server", "entry", 1));
1075 wait_for_start->Wait();
1076
1077 AutofillEntry syncapi_entry(MakeAutofillEntry("syncapi", "entry", 2));
1078 ASSERT_TRUE(AddAutofillSyncNode(syncapi_entry));
1079 VLOG(1) << "Syncapi update finished.";
1080
1081 // If we reach here, it means syncapi succeeded and we didn't deadlock. Yay!
1082 // Signal FakeServerUpdater that it can complete.
1083 wait_for_syncapi->Signal();
1084
1085 // Make another entry to ensure nothing broke afterwards and wait for finish
1086 // to clean up.
1087 updater->CreateNewEntryAndWait(MakeAutofillEntry("server2", "entry2", 3));
1088
1089 std::vector<AutofillEntry> sync_entries;
1090 std::vector<AutofillProfile> sync_profiles;
1091 ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles));
1092 EXPECT_EQ(3U, sync_entries.size());
1093 EXPECT_EQ(0U, sync_profiles.size());
1094 for (size_t i = 0; i < sync_entries.size(); i++) {
1095 VLOG(1) << "Entry " << i << ": " << sync_entries[i].key().name()
1096 << ", " << sync_entries[i].key().value();
1097 }
1098 }
1099