• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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