profile_sync_service_autofill_unittest.cc revision c407dc5cd9bdc5668497f21b26b09d988ab439de
1// Copyright (c) 2010 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/message_loop.h"
12#include "base/ref_counted.h"
13#include "base/scoped_ptr.h"
14#include "base/string16.h"
15#include "base/task.h"
16#include "base/time.h"
17#include "base/utf_string_conversions.h"
18#include "base/waitable_event.h"
19#include "chrome/browser/autofill/autofill_common_unittest.h"
20#include "chrome/browser/chrome_thread.h"
21#include "chrome/browser/sync/abstract_profile_sync_service_test.h"
22#include "chrome/browser/sync/engine/syncapi.h"
23#include "chrome/browser/sync/glue/autofill_change_processor.h"
24#include "chrome/browser/sync/glue/autofill_data_type_controller.h"
25#include "chrome/browser/sync/glue/autofill_model_associator.h"
26#include "chrome/browser/sync/profile_sync_factory.h"
27#include "chrome/browser/sync/profile_sync_service.h"
28#include "chrome/browser/sync/profile_sync_test_util.h"
29#include "chrome/browser/sync/protocol/autofill_specifics.pb.h"
30#include "chrome/browser/sync/syncable/model_type.h"
31#include "chrome/browser/sync/test_profile_sync_service.h"
32#include "chrome/browser/webdata/autofill_change.h"
33#include "chrome/browser/webdata/autofill_entry.h"
34#include "chrome/browser/webdata/web_database.h"
35#include "chrome/common/notification_source.h"
36#include "chrome/common/notification_type.h"
37#include "chrome/test/profile_mock.h"
38#include "testing/gmock/include/gmock/gmock.h"
39
40using base::Time;
41using base::WaitableEvent;
42using browser_sync::AutofillChangeProcessor;
43using browser_sync::AutofillDataTypeController;
44using browser_sync::AutofillModelAssociator;
45using syncable::WriteTransaction;
46using testing::_;
47using testing::DoAll;
48using testing::DoDefault;
49using testing::ElementsAre;
50using testing::Eq;
51using testing::Invoke;
52using testing::Return;
53using testing::SaveArg;
54using testing::SetArgumentPointee;
55
56class WebDatabaseMock : public WebDatabase {
57 public:
58  MOCK_METHOD2(RemoveFormElement,
59               bool(const string16& name, const string16& value));  // NOLINT
60  MOCK_METHOD1(GetAllAutofillEntries,
61               bool(std::vector<AutofillEntry>* entries));  // NOLINT
62  MOCK_METHOD3(GetAutofillTimestamps,
63               bool(const string16& name,  // NOLINT
64                    const string16& value,
65                    std::vector<base::Time>* timestamps));
66  MOCK_METHOD1(UpdateAutofillEntries,
67               bool(const std::vector<AutofillEntry>&));  // NOLINT
68  MOCK_METHOD1(GetAutoFillProfiles,
69               bool(std::vector<AutoFillProfile*>*));  // NOLINT
70  MOCK_METHOD1(UpdateAutoFillProfile,
71               bool(const AutoFillProfile&));  // NOLINT
72  MOCK_METHOD1(AddAutoFillProfile,
73               bool(const AutoFillProfile&));  // NOLINT
74  MOCK_METHOD1(RemoveAutoFillProfile,
75               bool(int));  // NOLINT
76};
77
78class WebDataServiceFake : public WebDataService {
79 public:
80  explicit WebDataServiceFake(WebDatabase* web_database)
81      : web_database_(web_database) {}
82  virtual bool IsDatabaseLoaded() {
83    return true;
84  }
85
86  virtual WebDatabase* GetDatabase() {
87    return web_database_;
88  }
89
90 private:
91  WebDatabase* web_database_;
92};
93
94class PersonalDataManagerMock: public PersonalDataManager {
95 public:
96  MOCK_CONST_METHOD0(IsDataLoaded, bool());
97  MOCK_METHOD0(LoadProfiles, void());
98  MOCK_METHOD0(LoadCreditCards, void());
99  MOCK_METHOD0(Refresh, void());
100};
101
102ACTION_P4(MakeAutofillSyncComponents, service, wd, pdm, dtc) {
103  EXPECT_TRUE(ChromeThread::CurrentlyOn(ChromeThread::DB));
104  if (!ChromeThread::CurrentlyOn(ChromeThread::DB))
105    return ProfileSyncFactory::SyncComponents(NULL, NULL);
106  AutofillModelAssociator* model_associator =
107      new AutofillModelAssociator(service, wd, pdm);
108  AutofillChangeProcessor* change_processor =
109      new AutofillChangeProcessor(model_associator, wd, pdm, dtc);
110  return ProfileSyncFactory::SyncComponents(model_associator,
111                                            change_processor);
112}
113
114class ProfileSyncServiceAutofillTest : public AbstractProfileSyncServiceTest {
115 protected:
116  ProfileSyncServiceAutofillTest() : db_thread_(ChromeThread::DB) {
117  }
118
119  virtual void SetUp() {
120    web_data_service_ = new WebDataServiceFake(&web_database_);
121    personal_data_manager_ = new PersonalDataManagerMock();
122    EXPECT_CALL(*personal_data_manager_, LoadProfiles()).Times(1);
123    EXPECT_CALL(*personal_data_manager_, LoadCreditCards()).Times(1);
124    personal_data_manager_->Init(&profile_);
125    db_thread_.Start();
126
127    notification_service_ = new ThreadNotificationService(&db_thread_);
128    notification_service_->Init();
129  }
130
131  virtual void TearDown() {
132    service_.reset();
133    notification_service_->TearDown();
134    db_thread_.Stop();
135    MessageLoop::current()->RunAllPending();
136  }
137
138  void StartSyncService(Task* task, bool will_fail_association) {
139    if (!service_.get()) {
140      service_.reset(
141          new TestProfileSyncService(&factory_, &profile_, false, false,
142                                     task));
143      AutofillDataTypeController* data_type_controller =
144          new AutofillDataTypeController(&factory_,
145                                         &profile_,
146                                         service_.get());
147
148      EXPECT_CALL(factory_, CreateAutofillSyncComponents(_, _, _, _)).
149          WillOnce(MakeAutofillSyncComponents(service_.get(),
150                                              &web_database_,
151                                              personal_data_manager_.get(),
152                                              data_type_controller));
153      EXPECT_CALL(factory_, CreateDataTypeManager(_, _)).
154          WillOnce(ReturnNewDataTypeManager());
155
156      EXPECT_CALL(profile_, GetWebDataService(_)).
157          WillOnce(Return(web_data_service_.get()));
158
159      EXPECT_CALL(profile_, GetPersonalDataManager()).
160          WillRepeatedly(Return(personal_data_manager_.get()));
161
162      EXPECT_CALL(*personal_data_manager_, IsDataLoaded()).
163          WillRepeatedly(Return(true));
164
165      service_->set_num_expected_resumes(will_fail_association ? 0 : 1);
166      service_->RegisterDataTypeController(data_type_controller);
167      service_->Initialize();
168      MessageLoop::current()->Run();
169    }
170  }
171
172  bool AddAutofillSyncNode(const AutofillEntry& entry) {
173    sync_api::WriteTransaction trans(
174        service_->backend()->GetUserShareHandle());
175    sync_api::ReadNode autofill_root(&trans);
176    if (!autofill_root.InitByTagLookup(browser_sync::kAutofillTag))
177      return false;
178
179    sync_api::WriteNode node(&trans);
180    std::string tag = AutofillModelAssociator::KeyToTag(entry.key().name(),
181                                                        entry.key().value());
182    if (!node.InitUniqueByCreation(syncable::AUTOFILL, autofill_root, tag))
183      return false;
184
185    AutofillChangeProcessor::WriteAutofillEntry(entry, &node);
186    return true;
187  }
188
189  bool AddAutofillProfileSyncNode(const AutoFillProfile& profile) {
190    sync_api::WriteTransaction trans(
191        service_->backend()->GetUserShareHandle());
192    sync_api::ReadNode autofill_root(&trans);
193    if (!autofill_root.InitByTagLookup(browser_sync::kAutofillTag))
194      return false;
195    sync_api::WriteNode node(&trans);
196    std::string tag = AutofillModelAssociator::ProfileLabelToTag(
197        profile.Label());
198    if (!node.InitUniqueByCreation(syncable::AUTOFILL, autofill_root, tag))
199      return false;
200    AutofillChangeProcessor::WriteAutofillProfile(profile, &node);
201    sync_pb::AutofillSpecifics s(node.GetAutofillSpecifics());
202    s.mutable_profile()->set_label(UTF16ToUTF8(profile.Label()));
203    node.SetAutofillSpecifics(s);
204    return true;
205  }
206
207  bool GetAutofillEntriesFromSyncDB(std::vector<AutofillEntry>* entries,
208                                    std::vector<AutoFillProfile>* profiles) {
209    sync_api::ReadTransaction trans(service_->backend()->GetUserShareHandle());
210    sync_api::ReadNode autofill_root(&trans);
211    if (!autofill_root.InitByTagLookup(browser_sync::kAutofillTag))
212      return false;
213
214    int64 child_id = autofill_root.GetFirstChildId();
215    while (child_id != sync_api::kInvalidId) {
216      sync_api::ReadNode child_node(&trans);
217      if (!child_node.InitByIdLookup(child_id))
218        return false;
219
220      const sync_pb::AutofillSpecifics& autofill(
221          child_node.GetAutofillSpecifics());
222      if (autofill.has_value()) {
223        AutofillKey key(UTF8ToUTF16(autofill.name()),
224                        UTF8ToUTF16(autofill.value()));
225        std::vector<base::Time> timestamps;
226        int timestamps_count = autofill.usage_timestamp_size();
227        for (int i = 0; i < timestamps_count; ++i) {
228          timestamps.push_back(Time::FromInternalValue(
229              autofill.usage_timestamp(i)));
230        }
231        entries->push_back(AutofillEntry(key, timestamps));
232      } else if (autofill.has_profile()) {
233        AutoFillProfile p(UTF8ToUTF16(autofill.profile().label()), 0);
234        AutofillModelAssociator::OverwriteProfileWithServerData(&p,
235            autofill.profile());
236        profiles->push_back(p);
237      }
238      child_id = child_node.GetSuccessorId();
239    }
240    return true;
241  }
242
243  void SetIdleChangeProcessorExpectations() {
244    EXPECT_CALL(web_database_, RemoveFormElement(_, _)).Times(0);
245    EXPECT_CALL(web_database_, GetAutofillTimestamps(_, _, _)).Times(0);
246    EXPECT_CALL(web_database_, UpdateAutofillEntries(_)).Times(0);
247  }
248
249  static AutofillEntry MakeAutofillEntry(const char* name,
250                                         const char* value,
251                                         time_t timestamp0,
252                                         time_t timestamp1) {
253    std::vector<Time> timestamps;
254    if (timestamp0 > 0)
255      timestamps.push_back(Time::FromTimeT(timestamp0));
256    if (timestamp1 > 0)
257      timestamps.push_back(Time::FromTimeT(timestamp1));
258    return AutofillEntry(
259        AutofillKey(ASCIIToUTF16(name), ASCIIToUTF16(value)), timestamps);
260  }
261
262  static AutofillEntry MakeAutofillEntry(const char* name,
263                                         const char* value,
264                                         time_t timestamp) {
265    return MakeAutofillEntry(name, value, timestamp, -1);
266  }
267
268  friend class AddAutofillEntriesTask;
269
270  ChromeThread db_thread_;
271  scoped_refptr<ThreadNotificationService> notification_service_;
272
273  ProfileMock profile_;
274  WebDatabaseMock web_database_;
275  scoped_refptr<WebDataService> web_data_service_;
276  scoped_refptr<PersonalDataManagerMock> personal_data_manager_;
277};
278
279class AddAutofillEntriesTask : public Task {
280 public:
281  AddAutofillEntriesTask(ProfileSyncServiceAutofillTest* test,
282                         const std::vector<AutofillEntry>& entries,
283                         const std::vector<AutoFillProfile>& profiles)
284      : test_(test), entries_(entries), profiles_(profiles), success_(false) {
285  }
286
287  virtual void Run() {
288    if (!test_->CreateRoot(syncable::AUTOFILL))
289      return;
290    for (size_t i = 0; i < entries_.size(); ++i) {
291      if (!test_->AddAutofillSyncNode(entries_[i]))
292        return;
293    }
294    for (size_t i = 0; i < profiles_.size(); ++i) {
295      if (!test_->AddAutofillProfileSyncNode(profiles_[i]))
296        return;
297    }
298    success_ = true;
299  }
300
301  bool success() { return success_; }
302
303 private:
304  ProfileSyncServiceAutofillTest* test_;
305  const std::vector<AutofillEntry>& entries_;
306  const std::vector<AutoFillProfile>& profiles_;
307  bool success_;
308};
309
310// TODO(skrul): Test abort startup.
311// TODO(skrul): Test processing of cloud changes.
312// TODO(tim): Add autofill data type controller test, and a case to cover
313//            waiting for the PersonalDataManager.
314TEST_F(ProfileSyncServiceAutofillTest, FailModelAssociation) {
315  // Don't create the root autofill node so startup fails.
316  StartSyncService(NULL, true);
317  EXPECT_TRUE(service_->unrecoverable_error_detected());
318}
319
320TEST_F(ProfileSyncServiceAutofillTest, EmptyNativeEmptySync) {
321  EXPECT_CALL(web_database_, GetAllAutofillEntries(_)).WillOnce(Return(true));
322  EXPECT_CALL(web_database_, GetAutoFillProfiles(_)).WillOnce(Return(true));
323  SetIdleChangeProcessorExpectations();
324  CreateRootTask task(this, syncable::AUTOFILL);
325  EXPECT_CALL(*personal_data_manager_, Refresh());
326  StartSyncService(&task, false);
327  ASSERT_TRUE(task.success());
328  std::vector<AutofillEntry> sync_entries;
329  std::vector<AutoFillProfile> sync_profiles;
330  ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles));
331  EXPECT_EQ(0U, sync_entries.size());
332  EXPECT_EQ(0U, sync_profiles.size());
333}
334
335TEST_F(ProfileSyncServiceAutofillTest, HasNativeEntriesEmptySync) {
336  std::vector<AutofillEntry> entries;
337  entries.push_back(MakeAutofillEntry("foo", "bar", 1));
338  EXPECT_CALL(web_database_, GetAllAutofillEntries(_)).
339      WillOnce(DoAll(SetArgumentPointee<0>(entries), Return(true)));
340  EXPECT_CALL(web_database_, GetAutoFillProfiles(_)).WillOnce(Return(true));
341  SetIdleChangeProcessorExpectations();
342  CreateRootTask task(this, syncable::AUTOFILL);
343  EXPECT_CALL(*personal_data_manager_, Refresh());
344  StartSyncService(&task, false);
345  ASSERT_TRUE(task.success());
346  std::vector<AutofillEntry> sync_entries;
347  std::vector<AutoFillProfile> sync_profiles;
348  ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles));
349  ASSERT_EQ(1U, entries.size());
350  EXPECT_TRUE(entries[0] == sync_entries[0]);
351  EXPECT_EQ(0U, sync_profiles.size());
352}
353
354TEST_F(ProfileSyncServiceAutofillTest, HasMixedNativeEmptySync) {
355  std::vector<AutofillEntry> entries;
356  entries.push_back(MakeAutofillEntry("foo", "bar", 1));
357  EXPECT_CALL(web_database_, GetAllAutofillEntries(_)).
358      WillOnce(DoAll(SetArgumentPointee<0>(entries), Return(true)));
359
360  std::vector<AutoFillProfile*> profiles;
361  std::vector<AutoFillProfile> expected_profiles;
362  // Owned by GetAutoFillProfiles caller.
363  AutoFillProfile* profile0 = new AutoFillProfile(string16(), 0);
364  autofill_unittest::SetProfileInfo(profile0,
365      "Billing", "Marion", "Mitchell", "Morrison",
366      "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
367      "91601", "US", "12345678910", "01987654321");
368  profiles.push_back(profile0);
369  expected_profiles.push_back(*profile0);
370  EXPECT_CALL(web_database_, GetAutoFillProfiles(_)).
371      WillOnce(DoAll(SetArgumentPointee<0>(profiles), Return(true)));
372  EXPECT_CALL(*personal_data_manager_, Refresh());
373  SetIdleChangeProcessorExpectations();
374  CreateRootTask task(this, syncable::AUTOFILL);
375  StartSyncService(&task, false);
376  ASSERT_TRUE(task.success());
377  std::vector<AutofillEntry> sync_entries;
378  std::vector<AutoFillProfile> sync_profiles;
379  ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles));
380  ASSERT_EQ(1U, entries.size());
381  EXPECT_TRUE(entries[0] == sync_entries[0]);
382  EXPECT_EQ(1U, sync_profiles.size());
383  EXPECT_EQ(expected_profiles[0], sync_profiles[0]);
384}
385
386bool ProfilesMatchExceptLabelImpl(AutoFillProfile p1, AutoFillProfile p2) {
387  const AutoFillFieldType types[] = { NAME_FIRST,
388                                      NAME_MIDDLE,
389                                      NAME_LAST,
390                                      EMAIL_ADDRESS,
391                                      COMPANY_NAME,
392                                      ADDRESS_HOME_LINE1,
393                                      ADDRESS_HOME_LINE2,
394                                      ADDRESS_HOME_CITY,
395                                      ADDRESS_HOME_STATE,
396                                      ADDRESS_HOME_ZIP,
397                                      ADDRESS_HOME_COUNTRY,
398                                      PHONE_HOME_NUMBER,
399                                      PHONE_FAX_NUMBER };
400  if (p1.Label() == p2.Label())
401    return false;
402
403  for (size_t index = 0; index < arraysize(types); ++index) {
404    if (p1.GetFieldText(AutoFillType(types[index])) !=
405        p2.GetFieldText(AutoFillType(types[index])))
406      return false;
407  }
408  return true;
409}
410
411MATCHER_P(ProfileMatchesExceptLabel, profile, "") {
412  return ProfilesMatchExceptLabelImpl(arg, profile);
413}
414
415TEST_F(ProfileSyncServiceAutofillTest, HasDuplicateProfileLabelsEmptySync) {
416  std::vector<AutoFillProfile> expected_profiles;
417  std::vector<AutoFillProfile*> profiles;
418  AutoFillProfile* profile0 = new AutoFillProfile(string16(), 0);
419  autofill_unittest::SetProfileInfo(profile0,
420      "Billing", "Marion", "Mitchell", "Morrison",
421      "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
422      "91601", "US", "12345678910", "01987654321");
423  AutoFillProfile* profile1 = new AutoFillProfile(string16(), 0);
424  autofill_unittest::SetProfileInfo(profile1,
425      "Billing", "Same", "Label", "Morrison",
426      "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
427      "91601", "US", "12345678910", "01987654321");
428  profiles.push_back(profile0);
429  profiles.push_back(profile1);
430  expected_profiles.push_back(*profile0);
431  expected_profiles.push_back(*profile1);
432  AutoFillProfile relabelled_profile;
433  EXPECT_CALL(web_database_, GetAllAutofillEntries(_)).WillOnce(Return(true));
434  EXPECT_CALL(*personal_data_manager_, Refresh());
435  EXPECT_CALL(web_database_, GetAutoFillProfiles(_)).
436      WillOnce(DoAll(SetArgumentPointee<0>(profiles), Return(true)));
437  EXPECT_CALL(web_database_, UpdateAutoFillProfile(
438      ProfileMatchesExceptLabel(expected_profiles[1]))).
439      WillOnce(DoAll(SaveArg<0>(&relabelled_profile), Return(true)));
440
441  SetIdleChangeProcessorExpectations();
442  CreateRootTask task(this, syncable::AUTOFILL);
443  StartSyncService(&task, false);
444  ASSERT_TRUE(task.success());
445  std::vector<AutofillEntry> sync_entries;
446  std::vector<AutoFillProfile> sync_profiles;
447  ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles));
448  EXPECT_EQ(0U, sync_entries.size());
449  EXPECT_EQ(2U, sync_profiles.size());
450  EXPECT_EQ(expected_profiles[0], sync_profiles[1]);
451  EXPECT_TRUE(ProfilesMatchExceptLabelImpl(expected_profiles[1],
452                                           sync_profiles[0]));
453  EXPECT_EQ(sync_profiles[0].Label(), relabelled_profile.Label());
454}
455
456TEST_F(ProfileSyncServiceAutofillTest, HasNativeWithDuplicatesEmptySync) {
457  // There is buggy autofill code that allows duplicate name/value
458  // pairs to exist in the database with separate pair_ids.
459  std::vector<AutofillEntry> entries;
460  entries.push_back(MakeAutofillEntry("foo", "bar", 1));
461  entries.push_back(MakeAutofillEntry("dup", "", 2));
462  entries.push_back(MakeAutofillEntry("dup", "", 3));
463  EXPECT_CALL(web_database_, GetAllAutofillEntries(_)).
464      WillOnce(DoAll(SetArgumentPointee<0>(entries), Return(true)));
465  EXPECT_CALL(web_database_, GetAutoFillProfiles(_)).WillOnce(Return(true));
466  SetIdleChangeProcessorExpectations();
467  CreateRootTask task(this, syncable::AUTOFILL);
468  EXPECT_CALL(*personal_data_manager_, Refresh());
469  StartSyncService(&task, false);
470  ASSERT_TRUE(task.success());
471  std::vector<AutofillEntry> sync_entries;
472  std::vector<AutoFillProfile> sync_profiles;
473  ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles));
474  EXPECT_EQ(2U, sync_entries.size());
475}
476
477TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncNoMerge) {
478  AutofillEntry native_entry(MakeAutofillEntry("native", "entry", 1));
479  AutofillEntry sync_entry(MakeAutofillEntry("sync", "entry", 2));
480  AutoFillProfile sync_profile(string16(), 0);
481  autofill_unittest::SetProfileInfo(&sync_profile,
482      "Billing", "Marion", "Mitchell", "Morrison",
483      "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
484      "91601", "US", "12345678910", "01987654321");
485
486  AutoFillProfile* native_profile = new AutoFillProfile(string16(), 0);
487  autofill_unittest::SetProfileInfo(native_profile,
488      "Work", "Josephine", "Alicia", "Saenz",
489      "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
490      "32801", "US", "19482937549", "13502849239");
491
492  std::vector<AutofillEntry> native_entries;
493  native_entries.push_back(native_entry);
494  std::vector<AutoFillProfile*> native_profiles;
495  native_profiles.push_back(native_profile);
496
497  std::vector<AutoFillProfile> expected_profiles;
498  expected_profiles.push_back(*native_profile);
499  expected_profiles.push_back(sync_profile);
500
501  EXPECT_CALL(web_database_, GetAllAutofillEntries(_)).
502      WillOnce(DoAll(SetArgumentPointee<0>(native_entries), Return(true)));
503  EXPECT_CALL(web_database_, GetAutoFillProfiles(_)).
504      WillOnce(DoAll(SetArgumentPointee<0>(native_profiles), Return(true)));
505  std::vector<AutofillEntry> sync_entries;
506  sync_entries.push_back(sync_entry);
507  std::vector<AutoFillProfile> sync_profiles;
508  sync_profiles.push_back(sync_profile);
509  AddAutofillEntriesTask task(this, sync_entries, sync_profiles);
510
511  AutoFillProfile to_be_added(sync_profile);
512  to_be_added.set_unique_id(1);
513  EXPECT_CALL(web_database_, UpdateAutofillEntries(ElementsAre(sync_entry))).
514      WillOnce(Return(true));
515  EXPECT_CALL(web_database_, AddAutoFillProfile(Eq(to_be_added))).
516      WillOnce(Return(true));
517  EXPECT_CALL(*personal_data_manager_, Refresh());
518  StartSyncService(&task, false);
519  ASSERT_TRUE(task.success());
520
521  std::set<AutofillEntry> expected_entries;
522  expected_entries.insert(native_entry);
523  expected_entries.insert(sync_entry);
524
525  std::vector<AutofillEntry> new_sync_entries;
526  std::vector<AutoFillProfile> new_sync_profiles;
527  ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries,
528                                           &new_sync_profiles));
529  std::set<AutofillEntry> new_sync_entries_set(new_sync_entries.begin(),
530                                               new_sync_entries.end());
531
532  EXPECT_TRUE(expected_entries == new_sync_entries_set);
533  EXPECT_EQ(2U, new_sync_profiles.size());
534  EXPECT_EQ(expected_profiles[0], new_sync_profiles[0]);
535  EXPECT_EQ(expected_profiles[1], new_sync_profiles[1]);
536}
537
538TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncMergeEntry) {
539  AutofillEntry native_entry(MakeAutofillEntry("merge", "entry", 1));
540  AutofillEntry sync_entry(MakeAutofillEntry("merge", "entry", 2));
541  AutofillEntry merged_entry(MakeAutofillEntry("merge", "entry", 1, 2));
542
543  std::vector<AutofillEntry> native_entries;
544  native_entries.push_back(native_entry);
545  EXPECT_CALL(web_database_, GetAllAutofillEntries(_)).
546      WillOnce(DoAll(SetArgumentPointee<0>(native_entries), Return(true)));
547  EXPECT_CALL(web_database_, GetAutoFillProfiles(_)).WillOnce(Return(true));
548
549  std::vector<AutofillEntry> sync_entries;
550  std::vector<AutoFillProfile> sync_profiles;
551  sync_entries.push_back(sync_entry);
552  AddAutofillEntriesTask task(this, sync_entries, sync_profiles);
553
554  EXPECT_CALL(web_database_, UpdateAutofillEntries(ElementsAre(merged_entry))).
555      WillOnce(Return(true));
556  EXPECT_CALL(*personal_data_manager_, Refresh());
557  StartSyncService(&task, false);
558  ASSERT_TRUE(task.success());
559
560  std::vector<AutofillEntry> new_sync_entries;
561  std::vector<AutoFillProfile> new_sync_profiles;
562  ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries,
563                                           &new_sync_profiles));
564  ASSERT_EQ(1U, new_sync_entries.size());
565  EXPECT_TRUE(merged_entry == new_sync_entries[0]);
566}
567
568TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncMergeProfile) {
569  AutoFillProfile sync_profile(string16(), 0);
570  autofill_unittest::SetProfileInfo(&sync_profile,
571      "Billing", "Marion", "Mitchell", "Morrison",
572      "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
573      "91601", "US", "12345678910", "01987654321");
574
575  AutoFillProfile* native_profile = new AutoFillProfile(string16(), 0);
576  autofill_unittest::SetProfileInfo(native_profile,
577      "Billing", "Josephine", "Alicia", "Saenz",
578      "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
579      "32801", "US", "19482937549", "13502849239");
580
581  std::vector<AutoFillProfile*> native_profiles;
582  native_profiles.push_back(native_profile);
583  EXPECT_CALL(web_database_, GetAllAutofillEntries(_)). WillOnce(Return(true));
584  EXPECT_CALL(web_database_, GetAutoFillProfiles(_)).
585      WillOnce(DoAll(SetArgumentPointee<0>(native_profiles), Return(true)));
586
587  std::vector<AutofillEntry> sync_entries;
588  std::vector<AutoFillProfile> sync_profiles;
589  sync_profiles.push_back(sync_profile);
590  AddAutofillEntriesTask task(this, sync_entries, sync_profiles);
591
592  EXPECT_CALL(web_database_, UpdateAutoFillProfile(Eq(sync_profile))).
593      WillOnce(Return(true));
594  EXPECT_CALL(*personal_data_manager_, Refresh());
595  StartSyncService(&task, false);
596  ASSERT_TRUE(task.success());
597
598  std::vector<AutofillEntry> new_sync_entries;
599  std::vector<AutoFillProfile> new_sync_profiles;
600  ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries,
601                                           &new_sync_profiles));
602  ASSERT_EQ(1U, new_sync_profiles.size());
603  EXPECT_TRUE(sync_profile == new_sync_profiles[0]);
604}
605
606TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeAddEntry) {
607  EXPECT_CALL(web_database_, GetAllAutofillEntries(_)).WillOnce(Return(true));
608  EXPECT_CALL(web_database_, GetAutoFillProfiles(_)).WillOnce(Return(true));
609  EXPECT_CALL(*personal_data_manager_, Refresh());
610  SetIdleChangeProcessorExpectations();
611  CreateRootTask task(this, syncable::AUTOFILL);
612  StartSyncService(&task, false);
613  ASSERT_TRUE(task.success());
614
615  AutofillEntry added_entry(MakeAutofillEntry("added", "entry", 1));
616  std::vector<base::Time> timestamps(added_entry.timestamps());
617
618  EXPECT_CALL(web_database_, GetAutofillTimestamps(_, _, _)).
619      WillOnce(DoAll(SetArgumentPointee<2>(timestamps), Return(true)));
620
621  AutofillChangeList changes;
622  changes.push_back(AutofillChange(AutofillChange::ADD, added_entry.key()));
623  scoped_refptr<ThreadNotifier> notifier = new ThreadNotifier(&db_thread_);
624  notifier->Notify(NotificationType::AUTOFILL_ENTRIES_CHANGED,
625                   Source<WebDataService>(web_data_service_.get()),
626                   Details<AutofillChangeList>(&changes));
627
628  std::vector<AutofillEntry> new_sync_entries;
629  std::vector<AutoFillProfile> new_sync_profiles;
630  ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries,
631                                           &new_sync_profiles));
632  ASSERT_EQ(1U, new_sync_entries.size());
633  EXPECT_TRUE(added_entry == new_sync_entries[0]);
634}
635
636TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeAddProfile) {
637  EXPECT_CALL(web_database_, GetAllAutofillEntries(_)).WillOnce(Return(true));
638  EXPECT_CALL(web_database_, GetAutoFillProfiles(_)).WillOnce(Return(true));
639  EXPECT_CALL(*personal_data_manager_, Refresh());
640  SetIdleChangeProcessorExpectations();
641  CreateRootTask task(this, syncable::AUTOFILL);
642  StartSyncService(&task, false);
643  ASSERT_TRUE(task.success());
644
645  AutoFillProfile added_profile(string16(), 0);
646  autofill_unittest::SetProfileInfo(&added_profile,
647      "Billing", "Josephine", "Alicia", "Saenz",
648      "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
649      "32801", "US", "19482937549", "13502849239");
650
651  AutofillProfileChange change(AutofillProfileChange::ADD,
652      added_profile.Label(), &added_profile, string16());
653  scoped_refptr<ThreadNotifier> notifier = new ThreadNotifier(&db_thread_);
654  notifier->Notify(NotificationType::AUTOFILL_PROFILE_CHANGED,
655                   Source<WebDataService>(web_data_service_.get()),
656                   Details<AutofillProfileChange>(&change));
657
658  std::vector<AutofillEntry> new_sync_entries;
659  std::vector<AutoFillProfile> new_sync_profiles;
660  ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries,
661                                           &new_sync_profiles));
662  ASSERT_EQ(1U, new_sync_profiles.size());
663  EXPECT_TRUE(added_profile == new_sync_profiles[0]);
664}
665
666TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeAddProfileConflict) {
667  AutoFillProfile sync_profile(string16(), 0);
668  autofill_unittest::SetProfileInfo(&sync_profile,
669      "Billing", "Marion", "Mitchell", "Morrison",
670      "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
671      "91601", "US", "12345678910", "01987654321");
672
673  std::vector<AutofillEntry> sync_entries;
674  std::vector<AutoFillProfile> sync_profiles;
675  sync_profiles.push_back(sync_profile);
676  AddAutofillEntriesTask task(this, sync_entries, sync_profiles);
677
678  sync_profile.set_unique_id(1);
679  EXPECT_CALL(web_database_, GetAllAutofillEntries(_)).WillOnce(Return(true));
680  EXPECT_CALL(web_database_, GetAutoFillProfiles(_)).WillOnce(Return(true));
681  EXPECT_CALL(web_database_, AddAutoFillProfile(Eq(sync_profile))).
682              WillOnce(Return(true));
683  EXPECT_CALL(*personal_data_manager_, Refresh());
684  SetIdleChangeProcessorExpectations();
685  StartSyncService(&task, false);
686  ASSERT_TRUE(task.success());
687
688  AutoFillProfile added_profile(string16(), 0);
689  autofill_unittest::SetProfileInfo(&added_profile,
690      "Billing", "Josephine", "Alicia", "Saenz",
691      "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
692      "32801", "US", "19482937549", "13502849239");
693
694  AutofillProfileChange change(AutofillProfileChange::ADD,
695      added_profile.Label(), &added_profile, string16());
696
697  AutoFillProfile relabelled_profile;
698  EXPECT_CALL(web_database_, UpdateAutoFillProfile(
699      ProfileMatchesExceptLabel(added_profile))).
700      WillOnce(DoAll(SaveArg<0>(&relabelled_profile), Return(true)));
701  EXPECT_CALL(*personal_data_manager_, Refresh());
702
703  scoped_refptr<ThreadNotifier> notifier = new ThreadNotifier(&db_thread_);
704  notifier->Notify(NotificationType::AUTOFILL_PROFILE_CHANGED,
705                   Source<WebDataService>(web_data_service_.get()),
706                   Details<AutofillProfileChange>(&change));
707
708  std::vector<AutofillEntry> new_sync_entries;
709  std::vector<AutoFillProfile> new_sync_profiles;
710  ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries,
711                                           &new_sync_profiles));
712  ASSERT_EQ(2U, new_sync_profiles.size());
713  sync_profile.set_unique_id(0);  // The sync DB doesn't store IDs.
714  EXPECT_EQ(sync_profile, new_sync_profiles[1]);
715  EXPECT_TRUE(ProfilesMatchExceptLabelImpl(added_profile,
716                                           new_sync_profiles[0]));
717  EXPECT_EQ(new_sync_profiles[0].Label(), relabelled_profile.Label());
718}
719
720TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeUpdateEntry) {
721  AutofillEntry original_entry(MakeAutofillEntry("my", "entry", 1));
722  std::vector<AutofillEntry> original_entries;
723  original_entries.push_back(original_entry);
724
725  EXPECT_CALL(web_database_, GetAllAutofillEntries(_)).
726      WillOnce(DoAll(SetArgumentPointee<0>(original_entries), Return(true)));
727  EXPECT_CALL(web_database_, GetAutoFillProfiles(_)).WillOnce(Return(true));
728  EXPECT_CALL(*personal_data_manager_, Refresh());
729  CreateRootTask task(this, syncable::AUTOFILL);
730  StartSyncService(&task, false);
731  ASSERT_TRUE(task.success());
732
733  AutofillEntry updated_entry(MakeAutofillEntry("my", "entry", 1, 2));
734  std::vector<base::Time> timestamps(updated_entry.timestamps());
735
736  EXPECT_CALL(web_database_, GetAutofillTimestamps(_, _, _)).
737      WillOnce(DoAll(SetArgumentPointee<2>(timestamps), Return(true)));
738
739  AutofillChangeList changes;
740  changes.push_back(AutofillChange(AutofillChange::UPDATE,
741                                   updated_entry.key()));
742  scoped_refptr<ThreadNotifier> notifier = new ThreadNotifier(&db_thread_);
743  notifier->Notify(NotificationType::AUTOFILL_ENTRIES_CHANGED,
744                   Source<WebDataService>(web_data_service_.get()),
745                   Details<AutofillChangeList>(&changes));
746
747  std::vector<AutofillEntry> new_sync_entries;
748  std::vector<AutoFillProfile> new_sync_profiles;
749  ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries,
750                                           &new_sync_profiles));
751  ASSERT_EQ(1U, new_sync_entries.size());
752  EXPECT_TRUE(updated_entry == new_sync_entries[0]);
753}
754
755
756TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeUpdateProfile) {
757  AutoFillProfile* native_profile = new AutoFillProfile(string16(), 0);
758  autofill_unittest::SetProfileInfo(native_profile,
759      "Billing", "Josephine", "Alicia", "Saenz",
760      "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
761      "32801", "US", "19482937549", "13502849239");
762  std::vector<AutoFillProfile*> native_profiles;
763  native_profiles.push_back(native_profile);
764  EXPECT_CALL(web_database_, GetAllAutofillEntries(_)). WillOnce(Return(true));
765  EXPECT_CALL(web_database_, GetAutoFillProfiles(_)).
766      WillOnce(DoAll(SetArgumentPointee<0>(native_profiles), Return(true)));
767  EXPECT_CALL(*personal_data_manager_, Refresh());
768  CreateRootTask task(this, syncable::AUTOFILL);
769  StartSyncService(&task, false);
770  ASSERT_TRUE(task.success());
771
772  AutoFillProfile update_profile(string16(), 0);
773  autofill_unittest::SetProfileInfo(&update_profile,
774      "Billing", "Changin'", "Mah", "Namez",
775      "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
776      "32801", "US", "19482937549", "13502849239");
777
778  AutofillProfileChange change(AutofillProfileChange::UPDATE,
779                               update_profile.Label(), &update_profile,
780                               ASCIIToUTF16("Billing"));
781  scoped_refptr<ThreadNotifier> notifier = new ThreadNotifier(&db_thread_);
782  notifier->Notify(NotificationType::AUTOFILL_PROFILE_CHANGED,
783                   Source<WebDataService>(web_data_service_.get()),
784                   Details<AutofillProfileChange>(&change));
785
786  std::vector<AutofillEntry> new_sync_entries;
787  std::vector<AutoFillProfile> new_sync_profiles;
788  ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries,
789                                           &new_sync_profiles));
790  ASSERT_EQ(1U, new_sync_profiles.size());
791  EXPECT_TRUE(update_profile == new_sync_profiles[0]);
792}
793
794TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeUpdateProfileRelabel) {
795  AutoFillProfile* native_profile = new AutoFillProfile(string16(), 0);
796  autofill_unittest::SetProfileInfo(native_profile,
797      "Billing", "Josephine", "Alicia", "Saenz",
798      "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
799      "32801", "US", "19482937549", "13502849239");
800  std::vector<AutoFillProfile*> native_profiles;
801  native_profiles.push_back(native_profile);
802  EXPECT_CALL(web_database_, GetAllAutofillEntries(_)). WillOnce(Return(true));
803  EXPECT_CALL(web_database_, GetAutoFillProfiles(_)).
804      WillOnce(DoAll(SetArgumentPointee<0>(native_profiles), Return(true)));
805  EXPECT_CALL(*personal_data_manager_, Refresh());
806  CreateRootTask task(this, syncable::AUTOFILL);
807  StartSyncService(&task, false);
808  ASSERT_TRUE(task.success());
809
810  AutoFillProfile update_profile(string16(), 0);
811  autofill_unittest::SetProfileInfo(&update_profile,
812      "TRYIN 2 FOOL U", "Josephine", "Alicia", "Saenz",
813      "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
814      "32801", "US", "19482937549", "13502849239");
815
816  AutofillProfileChange change(AutofillProfileChange::UPDATE,
817                               update_profile.Label(), &update_profile,
818                               ASCIIToUTF16("Billing"));
819  scoped_refptr<ThreadNotifier> notifier = new ThreadNotifier(&db_thread_);
820  notifier->Notify(NotificationType::AUTOFILL_PROFILE_CHANGED,
821                   Source<WebDataService>(web_data_service_.get()),
822                   Details<AutofillProfileChange>(&change));
823
824  std::vector<AutofillEntry> new_sync_entries;
825  std::vector<AutoFillProfile> new_sync_profiles;
826  ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries,
827                                           &new_sync_profiles));
828  ASSERT_EQ(1U, new_sync_profiles.size());
829  EXPECT_TRUE(update_profile == new_sync_profiles[0]);
830}
831
832TEST_F(ProfileSyncServiceAutofillTest,
833       ProcessUserChangeUpdateProfileRelabelConflict) {
834  AutoFillProfile* native_profile = new AutoFillProfile(string16(), 0);
835  autofill_unittest::SetProfileInfo(native_profile,
836      "Billing", "Josephine", "Alicia", "Saenz",
837      "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
838      "32801", "US", "19482937549", "13502849239");
839  AutoFillProfile* native_profile2 = new AutoFillProfile(string16(), 0);
840  autofill_unittest::SetProfileInfo(native_profile2,
841      "ExistingLabel", "Marion", "Mitchell", "Morrison",
842      "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
843      "91601", "US", "12345678910", "01987654321");
844  std::vector<AutoFillProfile*> native_profiles;
845  native_profiles.push_back(native_profile);
846  native_profiles.push_back(native_profile2);
847  AutoFillProfile marion(*native_profile2);
848  AutoFillProfile josephine_update(*native_profile);
849
850  EXPECT_CALL(web_database_, GetAllAutofillEntries(_)). WillOnce(Return(true));
851  EXPECT_CALL(web_database_, GetAutoFillProfiles(_)).
852      WillOnce(DoAll(SetArgumentPointee<0>(native_profiles), Return(true)));
853  EXPECT_CALL(*personal_data_manager_, Refresh());
854  CreateRootTask task(this, syncable::AUTOFILL);
855  StartSyncService(&task, false);
856  ASSERT_TRUE(task.success());
857
858  josephine_update.set_label(ASCIIToUTF16("ExistingLabel"));
859  AutoFillProfile relabelled_profile;
860  EXPECT_CALL(web_database_, UpdateAutoFillProfile(
861      ProfileMatchesExceptLabel(josephine_update))).
862      WillOnce(DoAll(SaveArg<0>(&relabelled_profile), Return(true)));
863  EXPECT_CALL(*personal_data_manager_, Refresh());
864
865  AutofillProfileChange change(AutofillProfileChange::UPDATE,
866                               josephine_update.Label(), &josephine_update,
867                               ASCIIToUTF16("Billing"));
868  scoped_refptr<ThreadNotifier> notifier = new ThreadNotifier(&db_thread_);
869  notifier->Notify(NotificationType::AUTOFILL_PROFILE_CHANGED,
870                   Source<WebDataService>(web_data_service_.get()),
871                   Details<AutofillProfileChange>(&change));
872
873  std::vector<AutofillEntry> new_sync_entries;
874  std::vector<AutoFillProfile> new_sync_profiles;
875  ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries,
876                                           &new_sync_profiles));
877  ASSERT_EQ(2U, new_sync_profiles.size());
878  marion.set_unique_id(0);  // The sync DB doesn't store IDs.
879  EXPECT_EQ(marion, new_sync_profiles[1]);
880  EXPECT_TRUE(ProfilesMatchExceptLabelImpl(josephine_update,
881                                           new_sync_profiles[0]));
882  EXPECT_EQ(new_sync_profiles[0].Label(), relabelled_profile.Label());
883}
884
885TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeRemoveEntry) {
886  AutofillEntry original_entry(MakeAutofillEntry("my", "entry", 1));
887  std::vector<AutofillEntry> original_entries;
888  original_entries.push_back(original_entry);
889
890  EXPECT_CALL(web_database_, GetAllAutofillEntries(_)).
891      WillOnce(DoAll(SetArgumentPointee<0>(original_entries), Return(true)));
892  EXPECT_CALL(web_database_, GetAutoFillProfiles(_)).WillOnce(Return(true));
893  EXPECT_CALL(*personal_data_manager_, Refresh());
894  CreateRootTask task(this, syncable::AUTOFILL);
895  StartSyncService(&task, false);
896  ASSERT_TRUE(task.success());
897
898  AutofillChangeList changes;
899  changes.push_back(AutofillChange(AutofillChange::REMOVE,
900                                   original_entry.key()));
901  scoped_refptr<ThreadNotifier> notifier = new ThreadNotifier(&db_thread_);
902  notifier->Notify(NotificationType::AUTOFILL_ENTRIES_CHANGED,
903                   Source<WebDataService>(web_data_service_.get()),
904                   Details<AutofillChangeList>(&changes));
905
906  std::vector<AutofillEntry> new_sync_entries;
907  std::vector<AutoFillProfile> new_sync_profiles;
908  ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries,
909                                           &new_sync_profiles));
910  ASSERT_EQ(0U, new_sync_entries.size());
911}
912
913TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeRemoveProfile) {
914  AutoFillProfile sync_profile(string16(), 0);
915  autofill_unittest::SetProfileInfo(&sync_profile,
916      "Billing", "Josephine", "Alicia", "Saenz",
917      "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
918      "32801", "US", "19482937549", "13502849239");
919  AutoFillProfile* native_profile = new AutoFillProfile(string16(), 0);
920  autofill_unittest::SetProfileInfo(native_profile,
921      "Billing", "Josephine", "Alicia", "Saenz",
922      "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
923      "32801", "US", "19482937549", "13502849239");
924
925  std::vector<AutoFillProfile*> native_profiles;
926  native_profiles.push_back(native_profile);
927  EXPECT_CALL(web_database_, GetAllAutofillEntries(_)). WillOnce(Return(true));
928  EXPECT_CALL(web_database_, GetAutoFillProfiles(_)).
929      WillOnce(DoAll(SetArgumentPointee<0>(native_profiles), Return(true)));
930
931  std::vector<AutofillEntry> sync_entries;
932  std::vector<AutoFillProfile> sync_profiles;
933  sync_profiles.push_back(sync_profile);
934  AddAutofillEntriesTask task(this, sync_entries, sync_profiles);
935  EXPECT_CALL(*personal_data_manager_, Refresh());
936  StartSyncService(&task, false);
937  ASSERT_TRUE(task.success());
938
939  AutofillProfileChange change(AutofillProfileChange::REMOVE,
940                               sync_profile.Label(), NULL, string16());
941  scoped_refptr<ThreadNotifier> notifier = new ThreadNotifier(&db_thread_);
942  notifier->Notify(NotificationType::AUTOFILL_PROFILE_CHANGED,
943                   Source<WebDataService>(web_data_service_.get()),
944                   Details<AutofillProfileChange>(&change));
945
946  std::vector<AutofillEntry> new_sync_entries;
947  std::vector<AutoFillProfile> new_sync_profiles;
948  ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries,
949                                           &new_sync_profiles));
950  ASSERT_EQ(0U, new_sync_entries.size());
951}
952
953TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeError) {
954  EXPECT_CALL(web_database_, GetAllAutofillEntries(_)).WillOnce(Return(true));
955  EXPECT_CALL(web_database_, GetAutoFillProfiles(_)).WillOnce(Return(true));
956  EXPECT_CALL(*personal_data_manager_, Refresh());
957  CreateRootTask task(this, syncable::AUTOFILL);
958  StartSyncService(&task, false);
959  ASSERT_TRUE(task.success());
960
961  // Inject an evil entry into the sync db to conflict with the same
962  // entry added by the user.
963  AutofillEntry evil_entry(MakeAutofillEntry("evil", "entry", 1));
964  ASSERT_TRUE(AddAutofillSyncNode(evil_entry));
965
966  AutofillChangeList changes;
967  changes.push_back(AutofillChange(AutofillChange::ADD,
968                                   evil_entry.key()));
969  scoped_refptr<ThreadNotifier> notifier = new ThreadNotifier(&db_thread_);
970  notifier->Notify(NotificationType::AUTOFILL_ENTRIES_CHANGED,
971                   Source<WebDataService>(web_data_service_.get()),
972                   Details<AutofillChangeList>(&changes));
973
974  // Wait for the PPS to shut everything down and signal us.
975  ProfileSyncServiceObserverMock observer;
976  service_->AddObserver(&observer);
977  EXPECT_CALL(observer, OnStateChanged()).WillOnce(QuitUIMessageLoop());
978  MessageLoop::current()->Run();
979  EXPECT_TRUE(service_->unrecoverable_error_detected());
980
981  // Ensure future autofill notifications don't crash.
982  notifier->Notify(NotificationType::AUTOFILL_ENTRIES_CHANGED,
983                   Source<WebDataService>(web_data_service_.get()),
984                   Details<AutofillChangeList>(&changes));
985}
986