1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <set>
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string>
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <vector>
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "testing/gtest/include/gtest/gtest.h"
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/callback.h"
12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/ref_counted.h"
13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/message_loop.h"
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string16.h"
16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/synchronization/waitable_event.h"
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/task.h"
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/time.h"
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/utf_string_conversions.h"
20731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/browser/autofill/autofill_common_test.h"
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/abstract_profile_sync_service_test.h"
223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/sync/engine/model_changing_syncer_command.h"
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/engine/syncapi.h"
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/glue/autofill_change_processor.h"
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/glue/autofill_data_type_controller.h"
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/glue/autofill_model_associator.h"
273f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "chrome/browser/sync/glue/autofill_profile_change_processor.h"
283f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "chrome/browser/sync/glue/autofill_profile_data_type_controller.h"
293f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "chrome/browser/sync/glue/autofill_profile_model_associator.h"
303f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "chrome/browser/sync/glue/data_type_controller.h"
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/profile_sync_factory.h"
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/profile_sync_service.h"
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/profile_sync_test_util.h"
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/protocol/autofill_specifics.pb.h"
353f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "chrome/browser/sync/syncable/autofill_migration.h"
3672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/sync/syncable/directory_manager.h"
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/syncable/model_type.h"
38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/sync/syncable/syncable.h"
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/test_profile_sync_service.h"
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/webdata/autofill_change.h"
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/webdata/autofill_entry.h"
42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/webdata/autofill_table.h"
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/webdata/web_database.h"
443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/common/net/gaia/gaia_constants.h"
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/test/profile_mock.h"
463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/test/sync/engine/test_id_factory.h"
47dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h"
48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_source.h"
49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_type.h"
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "testing/gmock/include/gmock/gmock.h"
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing base::Time;
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing base::WaitableEvent;
543f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenusing browser_sync::AutofillChangeProcessor;
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing browser_sync::AutofillDataTypeController;
563f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenusing browser_sync::AutofillModelAssociator;
573f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenusing browser_sync::AutofillProfileChangeProcessor;
583f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenusing browser_sync::AutofillProfileDataTypeController;
593f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenusing browser_sync::AutofillProfileModelAssociator;
603f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenusing browser_sync::DataTypeController;
613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickusing browser_sync::GROUP_DB;
623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickusing browser_sync::kAutofillTag;
633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickusing browser_sync::SyncBackendHostForProfileSyncTest;
643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickusing browser_sync::UnrecoverableErrorHandler;
653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickusing syncable::CREATE_NEW_UPDATE_ITEM;
663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickusing syncable::AUTOFILL;
6772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenusing syncable::BASE_VERSION;
6872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenusing syncable::CREATE;
693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickusing syncable::GET_BY_SERVER_TAG;
703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickusing syncable::INVALID;
7172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenusing syncable::MutableEntry;
7272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenusing syncable::OriginalEntries;
733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickusing syncable::SERVER_PARENT_ID;
743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickusing syncable::SERVER_SPECIFICS;
7572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenusing syncable::SPECIFICS;
7672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenusing syncable::UNITTEST;
773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickusing syncable::WriterTag;
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing syncable::WriteTransaction;
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing testing::_;
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing testing::DoAll;
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing testing::DoDefault;
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing testing::ElementsAre;
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing testing::Eq;
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing testing::Invoke;
853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickusing testing::Mock;
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing testing::Return;
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing testing::SaveArg;
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing testing::SetArgumentPointee;
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merricknamespace syncable {
913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass Id;
923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
94ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass AutofillTableMock : public AutofillTable {
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
96ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AutofillTableMock() : AutofillTable(NULL, NULL) {}
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MOCK_METHOD2(RemoveFormElement,
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch               bool(const string16& name, const string16& value));  // NOLINT
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MOCK_METHOD1(GetAllAutofillEntries,
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch               bool(std::vector<AutofillEntry>* entries));  // NOLINT
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MOCK_METHOD3(GetAutofillTimestamps,
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch               bool(const string16& name,  // NOLINT
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    const string16& value,
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    std::vector<base::Time>* timestamps));
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MOCK_METHOD1(UpdateAutofillEntries,
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch               bool(const std::vector<AutofillEntry>&));  // NOLINT
107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  MOCK_METHOD1(GetAutofillProfiles,
108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen               bool(std::vector<AutofillProfile*>*));  // NOLINT
109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  MOCK_METHOD1(UpdateAutofillProfile,
110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen               bool(const AutofillProfile&));  // NOLINT
111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  MOCK_METHOD1(AddAutofillProfile,
112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen               bool(const AutofillProfile&));  // NOLINT
113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  MOCK_METHOD1(RemoveAutofillProfile,
11472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen               bool(const std::string&));  // NOLINT
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass WebDatabaseFake : public WebDatabase {
118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen public:
119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  explicit WebDatabaseFake(AutofillTable* autofill_table)
120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      : autofill_table_(autofill_table) {}
121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual AutofillTable* GetAutofillTable() {
123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return autofill_table_;
124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
126ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen private:
127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AutofillTable* autofill_table_;
128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen};
129ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
130ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1313f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenclass ProfileSyncServiceAutofillTest;
1323f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
133ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsentemplate<class AutofillProfile>
1343f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsensyncable::ModelType GetModelType() {
1353f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  return syncable::UNSPECIFIED;
1363f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
1373f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1383f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsentemplate<>
1393f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsensyncable::ModelType GetModelType<AutofillEntry>() {
1403f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  return syncable::AUTOFILL;
1413f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
1423f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1433f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsentemplate<>
144ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsensyncable::ModelType GetModelType<AutofillProfile>() {
1453f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  return syncable::AUTOFILL_PROFILE;
1463f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
1473f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass WebDataServiceFake : public WebDataService {
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  explicit WebDataServiceFake(WebDatabase* web_database)
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      : web_database_(web_database) {}
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual bool IsDatabaseLoaded() {
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual WebDatabase* GetDatabase() {
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return web_database_;
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WebDatabase* web_database_;
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochACTION_P4(MakeAutofillSyncComponents, service, wd, pdm, dtc) {
165731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB));
166731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (!BrowserThread::CurrentlyOn(BrowserThread::DB))
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return ProfileSyncFactory::SyncComponents(NULL, NULL);
1683f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  AutofillModelAssociator* model_associator =
1693f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      new AutofillModelAssociator(service, wd, pdm);
1703f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  AutofillChangeProcessor* change_processor =
1713f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      new AutofillChangeProcessor(model_associator, wd, pdm, dtc);
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return ProfileSyncFactory::SyncComponents(model_associator,
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                            change_processor);
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1763f50c38dc070f4bb515c1b64450dae14f316474eKristian MonsenACTION_P4(MakeAutofillProfileSyncComponents, service, wd, pdm, dtc) {
1773f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB));
1783f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  if (!BrowserThread::CurrentlyOn(BrowserThread::DB))
1793f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    return ProfileSyncFactory::SyncComponents(NULL, NULL);
1803f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  AutofillProfileModelAssociator* model_associator =
1813f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      new AutofillProfileModelAssociator(service, wd, pdm);
1823f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  AutofillProfileChangeProcessor* change_processor =
1833f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      new AutofillProfileChangeProcessor(model_associator, wd, pdm, dtc);
1843f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  return ProfileSyncFactory::SyncComponents(model_associator,
1853f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                            change_processor);
1863f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
1873f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1883f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenclass AbstractAutofillFactory {
1893f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen public:
1903f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  virtual AutofillDataTypeController* CreateDataTypeController(
1913f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    ProfileSyncFactory *factory,
1923f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      ProfileMock* profile,
1933f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      ProfileSyncService* service) = 0;
1943f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  virtual void SetExpectation(ProfileSyncFactoryMock* factory,
1953f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      ProfileSyncService* service,
1963f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      WebDatabase* wd,
1973f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      PersonalDataManager* pdm,
1983f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      DataTypeController* dtc) = 0;
1993f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  virtual ~AbstractAutofillFactory() {}
2003f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen};
2013f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2023f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenclass AutofillEntryFactory : public AbstractAutofillFactory {
2033f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen public:
2043f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  browser_sync::AutofillDataTypeController* CreateDataTypeController(
2053f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      ProfileSyncFactory *factory,
2063f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      ProfileMock* profile,
2073f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      ProfileSyncService* service) {
2083f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    return new AutofillDataTypeController(factory,
2093f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        profile,
2103f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        service);
2113f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  }
2123f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2133f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  void SetExpectation(ProfileSyncFactoryMock* factory,
2143f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      ProfileSyncService* service,
2153f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      WebDatabase* wd,
2163f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      PersonalDataManager* pdm,
2173f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      DataTypeController* dtc) {
2183f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    EXPECT_CALL(*factory, CreateAutofillSyncComponents(_,_,_,_)).
2193f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        WillOnce(MakeAutofillSyncComponents(service, wd, pdm, dtc));
2203f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  }
2213f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen};
2223f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2233f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenclass AutofillProfileFactory : public AbstractAutofillFactory {
2243f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen public:
2253f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  browser_sync::AutofillDataTypeController* CreateDataTypeController(
2263f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      ProfileSyncFactory *factory,
2273f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      ProfileMock* profile,
2283f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      ProfileSyncService* service) {
2293f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    return new AutofillProfileDataTypeController(factory,
2303f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        profile,
2313f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        service);
232ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
2333f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2343f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  void SetExpectation(ProfileSyncFactoryMock* factory,
2353f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      ProfileSyncService* service,
2363f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      WebDatabase* wd,
2373f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      PersonalDataManager* pdm,
2383f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      DataTypeController* dtc) {
2393f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    EXPECT_CALL(*factory, CreateAutofillProfileSyncComponents(_,_,_,_)).
2403f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        WillOnce(MakeAutofillProfileSyncComponents(service, wd, pdm, dtc));
2413f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  }
2423f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen};
2433f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2443f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenclass PersonalDataManagerMock: public PersonalDataManager {
2453f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen public:
2463f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  MOCK_CONST_METHOD0(IsDataLoaded, bool());
2473f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  MOCK_METHOD0(LoadProfiles, void());
2483f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  MOCK_METHOD0(LoadCreditCards, void());
2493f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  MOCK_METHOD0(Refresh, void());
2503f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen};
2513f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsentemplate <class T> class AddAutofillTask;
2523f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ProfileSyncServiceAutofillTest : public AbstractProfileSyncServiceTest {
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected:
255ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ProfileSyncServiceAutofillTest() : db_thread_(BrowserThread::DB) {}
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2573f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  AutofillProfileFactory profile_factory_;
2583f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  AutofillEntryFactory entry_factory_;
2593f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2603f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  AbstractAutofillFactory* GetFactory(syncable::ModelType type) {
2613f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    if (type == syncable::AUTOFILL) {
2623f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      return &entry_factory_;
2633f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    } else if (type == syncable::AUTOFILL_PROFILE) {
2643f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      return &profile_factory_;
2653f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    } else {
2663f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      NOTREACHED();
2673f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      return NULL;
2683f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    }
2693f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  }
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void SetUp() {
271ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    profile_.CreateRequestContext();
272ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    web_database_.reset(new WebDatabaseFake(&autofill_table_));
273ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    web_data_service_ = new WebDataServiceFake(web_database_.get());
274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    personal_data_manager_ = new PersonalDataManagerMock();
275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_CALL(*personal_data_manager_, LoadProfiles()).Times(1);
276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_CALL(*personal_data_manager_, LoadCreditCards()).Times(1);
277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    personal_data_manager_->Init(&profile_);
278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    db_thread_.Start();
279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    notification_service_ = new ThreadNotificationService(&db_thread_);
281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    notification_service_->Init();
282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void TearDown() {
285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    service_.reset();
286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    notification_service_->TearDown();
287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    db_thread_.Stop();
288ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    {
289ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // The request context gets deleted on the I/O thread. To prevent a leak
290ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // supply one here.
291ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      BrowserThread io_thread(BrowserThread::IO, MessageLoop::current());
292ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      profile_.ResetRequestContext();
293ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MessageLoop::current()->RunAllPending();
295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2973f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  void StartSyncService(Task* task,
2983f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                        bool will_fail_association,
2993f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                        syncable::ModelType type) {
3003f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    AbstractAutofillFactory* factory = GetFactory(type);
3013f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    service_.reset(
3023f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        new TestProfileSyncService(&factory_, &profile_, "test_user", false,
3033f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                   task));
3043f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    AutofillDataTypeController* data_type_controller =
3053f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        factory->CreateDataTypeController(&factory_,
3063f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen            &profile_,
3073f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen            service_.get());
308ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SyncBackendHostForProfileSyncTest::
309ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        SetDefaultExpectationsForWorkerCreation(&profile_);
3103f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
311ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    factory->SetExpectation(&factory_,
312ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                            service_.get(),
313ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                            web_database_.get(),
314ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                            personal_data_manager_.get(),
315ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                            data_type_controller);
3163f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
3173f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    EXPECT_CALL(factory_, CreateDataTypeManager(_, _)).
3183f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        WillOnce(ReturnNewDataTypeManager());
3193f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
3203f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    EXPECT_CALL(profile_, GetWebDataService(_)).
3213f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        WillOnce(Return(web_data_service_.get()));
3223f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
3233f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    EXPECT_CALL(profile_, GetPersonalDataManager()).
3243f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        WillRepeatedly(Return(personal_data_manager_.get()));
3253f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
3263f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    EXPECT_CALL(*personal_data_manager_, IsDataLoaded()).
3273f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        WillRepeatedly(Return(true));
3283f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
3293f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen     // We need tokens to get the tests going
3303f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    token_service_.IssueAuthTokenForTest(
3313f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        GaiaConstants::kSyncService, "token");
3323f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
3333f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    EXPECT_CALL(profile_, GetTokenService()).
3343f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        WillRepeatedly(Return(&token_service_));
3353f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
3363f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    service_->RegisterDataTypeController(data_type_controller);
3373f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    service_->Initialize();
3383f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    MessageLoop::current()->Run();
339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool AddAutofillSyncNode(const AutofillEntry& entry) {
34272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    sync_api::WriteTransaction trans(service_->GetUserShare());
343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    sync_api::ReadNode autofill_root(&trans);
344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!autofill_root.InitByTagLookup(browser_sync::kAutofillTag))
345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return false;
346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    sync_api::WriteNode node(&trans);
3483f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    std::string tag = AutofillModelAssociator::KeyToTag(entry.key().name(),
349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                        entry.key().value());
350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!node.InitUniqueByCreation(syncable::AUTOFILL, autofill_root, tag))
351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return false;
352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3533f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    AutofillChangeProcessor::WriteAutofillEntry(entry, &node);
354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
357ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool AddAutofillSyncNode(const AutofillProfile& profile) {
35872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    sync_api::WriteTransaction trans(service_->GetUserShare());
359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    sync_api::ReadNode autofill_root(&trans);
3603f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    if (!autofill_root.InitByTagLookup(browser_sync::kAutofillProfileTag))
361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return false;
362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    sync_api::WriteNode node(&trans);
3633f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    std::string tag = profile.guid();
3643f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    if (!node.InitUniqueByCreation(syncable::AUTOFILL_PROFILE,
3653f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        autofill_root, tag))
366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return false;
3673f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    AutofillProfileChangeProcessor::WriteAutofillProfile(profile, &node);
368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool GetAutofillEntriesFromSyncDB(std::vector<AutofillEntry>* entries,
372ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                    std::vector<AutofillProfile>* profiles) {
37372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    sync_api::ReadTransaction trans(service_->GetUserShare());
374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    sync_api::ReadNode autofill_root(&trans);
375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!autofill_root.InitByTagLookup(browser_sync::kAutofillTag))
376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return false;
377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int64 child_id = autofill_root.GetFirstChildId();
379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    while (child_id != sync_api::kInvalidId) {
380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      sync_api::ReadNode child_node(&trans);
381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (!child_node.InitByIdLookup(child_id))
382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        return false;
383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      const sync_pb::AutofillSpecifics& autofill(
385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          child_node.GetAutofillSpecifics());
386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (autofill.has_value()) {
387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        AutofillKey key(UTF8ToUTF16(autofill.name()),
388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        UTF8ToUTF16(autofill.value()));
389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        std::vector<base::Time> timestamps;
390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        int timestamps_count = autofill.usage_timestamp_size();
391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        for (int i = 0; i < timestamps_count; ++i) {
392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          timestamps.push_back(Time::FromInternalValue(
393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              autofill.usage_timestamp(i)));
394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        }
395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        entries->push_back(AutofillEntry(key, timestamps));
396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      } else if (autofill.has_profile()) {
397ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        AutofillProfile p;
3983f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        p.set_guid(autofill.profile().guid());
3993f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        AutofillProfileModelAssociator::OverwriteProfileWithServerData(&p,
400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            autofill.profile());
401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        profiles->push_back(p);
402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      child_id = child_node.GetSuccessorId();
404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4083f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  bool GetAutofillProfilesFromSyncDBUnderProfileNode(
409ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      std::vector<AutofillProfile>* profiles) {
41072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    sync_api::ReadTransaction trans(service_->GetUserShare());
4113f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    sync_api::ReadNode autofill_root(&trans);
4123f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    if (!autofill_root.InitByTagLookup(browser_sync::kAutofillProfileTag))
4133f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      return false;
4143f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
4153f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    int64 child_id = autofill_root.GetFirstChildId();
4163f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    while (child_id != sync_api::kInvalidId) {
4173f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      sync_api::ReadNode child_node(&trans);
4183f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      if (!child_node.InitByIdLookup(child_id))
4193f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        return false;
4203f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
4213f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      const sync_pb::AutofillProfileSpecifics& autofill(
4223f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen          child_node.GetAutofillProfileSpecifics());
423ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        AutofillProfile p;
4243f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        p.set_guid(autofill.guid());
4253f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        AutofillProfileModelAssociator::OverwriteProfileWithServerData(&p,
4263f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen            autofill);
4273f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        profiles->push_back(p);
4283f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      child_id = child_node.GetSuccessorId();
4293f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    }
4303f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    return true;
4313f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  }
4323f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void SetIdleChangeProcessorExpectations() {
434ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_CALL(autofill_table_, RemoveFormElement(_, _)).Times(0);
435ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_CALL(autofill_table_, GetAutofillTimestamps(_, _, _)).Times(0);
436ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_CALL(autofill_table_, UpdateAutofillEntries(_)).Times(0);
437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static AutofillEntry MakeAutofillEntry(const char* name,
440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                         const char* value,
441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                         time_t timestamp0,
442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                         time_t timestamp1) {
443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::vector<Time> timestamps;
444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (timestamp0 > 0)
445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      timestamps.push_back(Time::FromTimeT(timestamp0));
446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (timestamp1 > 0)
447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      timestamps.push_back(Time::FromTimeT(timestamp1));
448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return AutofillEntry(
449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        AutofillKey(ASCIIToUTF16(name), ASCIIToUTF16(value)), timestamps);
450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static AutofillEntry MakeAutofillEntry(const char* name,
453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                         const char* value,
454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                         time_t timestamp) {
455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return MakeAutofillEntry(name, value, timestamp, -1);
456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4583f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  friend class AddAutofillTask<AutofillEntry>;
459ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  friend class AddAutofillTask<AutofillProfile>;
4603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  friend class FakeServerUpdater;
461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
462731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread db_thread_;
463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<ThreadNotificationService> notification_service_;
464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ProfileMock profile_;
466ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AutofillTableMock autofill_table_;
467ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_ptr<WebDatabaseFake> web_database_;
468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<WebDataService> web_data_service_;
469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<PersonalDataManagerMock> personal_data_manager_;
470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4723f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsentemplate <class T>
4733f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenclass AddAutofillTask : public Task {
474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
4753f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  AddAutofillTask(ProfileSyncServiceAutofillTest* test,
4763f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                         const std::vector<T>& entries)
4773f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      : test_(test), entries_(entries), success_(false) {
478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void Run() {
4813f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    if (!test_->CreateRoot(GetModelType<T>()))
482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return;
483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (size_t i = 0; i < entries_.size(); ++i) {
484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (!test_->AddAutofillSyncNode(entries_[i]))
485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        return;
486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    success_ = true;
488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool success() { return success_; }
490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ProfileSyncServiceAutofillTest* test_;
4933f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  const std::vector<T>& entries_;
494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool success_;
495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Overload write transaction to use custom NotifyTransactionComplete
4983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickstatic const bool kLoggingInfo = true;
4993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass WriteTransactionTest: public WriteTransaction {
5003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick public:
50172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  WriteTransactionTest(const syncable::ScopedDirLookup& directory,
5023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       WriterTag writer, const char* source_file,
5033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       int line,
5043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       scoped_ptr<WaitableEvent> *wait_for_syncapi)
5053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      : WriteTransaction(directory, writer, source_file, line),
5063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        wait_for_syncapi_(wait_for_syncapi) { }
5073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
508ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void NotifyTransactionComplete(syncable::ModelTypeBitSet types) {
5093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // This is where we differ. Force a thread change here, giving another
5103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // thread a chance to create a WriteTransaction
5113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    (*wait_for_syncapi_)->Wait();
5123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
513ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    WriteTransaction::NotifyTransactionComplete(types);
5143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
5153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
5163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick private:
5173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_ptr<WaitableEvent> *wait_for_syncapi_;
5183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick};
5193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
5203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Our fake server updater. Needs the RefCountedThreadSafe inheritance so we can
5213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// post tasks with it.
5223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass FakeServerUpdater: public base::RefCountedThreadSafe<FakeServerUpdater> {
5233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick public:
5243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  FakeServerUpdater(TestProfileSyncService *service,
5253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    scoped_ptr<WaitableEvent> *wait_for_start,
5263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    scoped_ptr<WaitableEvent> *wait_for_syncapi)
5273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      : entry_(ProfileSyncServiceAutofillTest::MakeAutofillEntry("0", "0", 0)),
5283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        service_(service),
5293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        wait_for_start_(wait_for_start),
5303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        wait_for_syncapi_(wait_for_syncapi),
5313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        is_finished_(false, false) { }
5323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
5333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void Update() {
5343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // This gets called in a modelsafeworker thread.
535731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB));
5363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
53772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    sync_api::UserShare* user_share = service_->GetUserShare();
53872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    syncable::DirectoryManager* dir_manager = user_share->dir_manager.get();
53972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    syncable::ScopedDirLookup dir(dir_manager, user_share->name);
5403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    ASSERT_TRUE(dir.good());
5413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
5423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // Create autofill protobuf
5433f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    std::string tag = AutofillModelAssociator::KeyToTag(entry_.key().name(),
5443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                                        entry_.key().value());
5453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    sync_pb::AutofillSpecifics new_autofill;
5463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    new_autofill.set_name(UTF16ToUTF8(entry_.key().name()));
5473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    new_autofill.set_value(UTF16ToUTF8(entry_.key().value()));
5483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const std::vector<base::Time>& ts(entry_.timestamps());
5493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    for (std::vector<base::Time>::const_iterator timestamp = ts.begin();
5503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick         timestamp != ts.end(); ++timestamp) {
5513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      new_autofill.add_usage_timestamp(timestamp->ToInternalValue());
5523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
5533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
5543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    sync_pb::EntitySpecifics entity_specifics;
5553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    entity_specifics.MutableExtension(sync_pb::autofill)->
5563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        CopyFrom(new_autofill);
5573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
5583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    {
5593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      // Tell main thread we've started
5603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      (*wait_for_start_)->Signal();
5613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
5623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      // Create write transaction.
5633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      WriteTransactionTest trans(dir, UNITTEST, __FILE__, __LINE__,
5643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                 wait_for_syncapi_);
5653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
5663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      // Create actual entry based on autofill protobuf information.
5673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      // Simulates effects of SyncerUtil::UpdateLocalDataFromServerData
5683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      MutableEntry parent(&trans, GET_BY_SERVER_TAG, kAutofillTag);
5693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      MutableEntry item(&trans, CREATE, parent.Get(syncable::ID), tag);
5703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      ASSERT_TRUE(item.good());
5713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      item.Put(SPECIFICS, entity_specifics);
5723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      item.Put(SERVER_SPECIFICS, entity_specifics);
5733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      item.Put(BASE_VERSION, 1);
574dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      syncable::Id server_item_id = service_->id_factory()->NewServerId();
575dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      item.Put(syncable::ID, server_item_id);
576dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      syncable::Id new_predecessor;
5773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      ASSERT_TRUE(item.PutPredecessor(new_predecessor));
5783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
579731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    VLOG(1) << "FakeServerUpdater finishing.";
5803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    is_finished_.Signal();
5813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
5823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
5833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void CreateNewEntry(const AutofillEntry& entry) {
5843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    entry_ = entry;
5853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    scoped_ptr<Callback0::Type> c(NewCallback((FakeServerUpdater *)this,
5863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                              &FakeServerUpdater::Update));
5873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    std::vector<browser_sync::ModelSafeWorker*> workers;
58872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    service_->GetBackendForTest()->GetWorkers(&workers);
5893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
590731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    ASSERT_FALSE(BrowserThread::CurrentlyOn(BrowserThread::DB));
591731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    if (!BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
5923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick         NewRunnableMethod(this, &FakeServerUpdater::Update))) {
5933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      NOTREACHED() << "Failed to post task to the db thread.";
5943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      return;
5953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
5963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
5973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
5983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void CreateNewEntryAndWait(const AutofillEntry& entry) {
5993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    entry_ = entry;
6003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    scoped_ptr<Callback0::Type> c(NewCallback((FakeServerUpdater *)this,
6013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                              &FakeServerUpdater::Update));
6023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    std::vector<browser_sync::ModelSafeWorker*> workers;
60372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    service_->GetBackendForTest()->GetWorkers(&workers);
6043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
605731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    ASSERT_FALSE(BrowserThread::CurrentlyOn(BrowserThread::DB));
6063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    is_finished_.Reset();
607731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    if (!BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
6083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick         NewRunnableMethod(this, &FakeServerUpdater::Update))) {
6093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      NOTREACHED() << "Failed to post task to the db thread.";
6103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      return;
6113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
6123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    is_finished_.Wait();
6133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
6143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
6153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick private:
6163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  friend class base::RefCountedThreadSafe<FakeServerUpdater>;
6173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ~FakeServerUpdater() { }
6183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
6193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  AutofillEntry entry_;
6203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestProfileSyncService *service_;
6213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_ptr<WaitableEvent> *wait_for_start_;
6223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_ptr<WaitableEvent> *wait_for_syncapi_;
6233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  WaitableEvent is_finished_;
6243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  syncable::Id parent_id_;
6253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick};
6263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
627c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// TODO(skrul): Test abort startup.
628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// TODO(skrul): Test processing of cloud changes.
629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// TODO(tim): Add autofill data type controller test, and a case to cover
630c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//            waiting for the PersonalDataManager.
631c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ProfileSyncServiceAutofillTest, FailModelAssociation) {
632c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Don't create the root autofill node so startup fails.
6333f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  StartSyncService(NULL, true, syncable::AUTOFILL);
634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(service_->unrecoverable_error_detected());
635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
637c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ProfileSyncServiceAutofillTest, EmptyNativeEmptySync) {
638ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).WillOnce(Return(true));
639ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).WillOnce(Return(true));
640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SetIdleChangeProcessorExpectations();
641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CreateRootTask task(this, syncable::AUTOFILL);
642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_CALL(*personal_data_manager_, Refresh());
6433f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  StartSyncService(&task, false, syncable::AUTOFILL);
644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(task.success());
645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<AutofillEntry> sync_entries;
646ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<AutofillProfile> sync_profiles;
647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles));
648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0U, sync_entries.size());
649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0U, sync_profiles.size());
650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
652c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ProfileSyncServiceAutofillTest, HasNativeEntriesEmptySync) {
653c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<AutofillEntry> entries;
654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  entries.push_back(MakeAutofillEntry("foo", "bar", 1));
655ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).
656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      WillOnce(DoAll(SetArgumentPointee<0>(entries), Return(true)));
657ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).WillOnce(Return(true));
658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SetIdleChangeProcessorExpectations();
659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CreateRootTask task(this, syncable::AUTOFILL);
660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_CALL(*personal_data_manager_, Refresh());
6613f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  StartSyncService(&task, false, syncable::AUTOFILL);
662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(task.success());
663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<AutofillEntry> sync_entries;
664ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<AutofillProfile> sync_profiles;
665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles));
666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(1U, entries.size());
667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(entries[0] == sync_entries[0]);
668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0U, sync_profiles.size());
669c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
6713f50c38dc070f4bb515c1b64450dae14f316474eKristian MonsenTEST_F(ProfileSyncServiceAutofillTest, HasProfileEmptySync) {
672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
673ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<AutofillProfile*> profiles;
674ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<AutofillProfile> expected_profiles;
675ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Owned by GetAutofillProfiles caller.
676ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AutofillProfile* profile0 = new AutofillProfile;
6773f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  autofill_test::SetProfileInfoWithGuid(profile0,
678dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      "54B3F9AA-335E-4F71-A27D-719C41564230", "Billing",
6793f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      "Mitchell", "Morrison",
680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
681c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "91601", "US", "12345678910", "01987654321");
682c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  profiles.push_back(profile0);
683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  expected_profiles.push_back(*profile0);
684ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).
685c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      WillOnce(DoAll(SetArgumentPointee<0>(profiles), Return(true)));
686c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_CALL(*personal_data_manager_, Refresh());
687c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SetIdleChangeProcessorExpectations();
6883f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  CreateRootTask task(this, syncable::AUTOFILL_PROFILE);
6893f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  StartSyncService(&task, false, syncable::AUTOFILL_PROFILE);
690c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(task.success());
691ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<AutofillProfile> sync_profiles;
6923f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(&sync_profiles));
693c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1U, sync_profiles.size());
694513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  EXPECT_EQ(0, expected_profiles[0].Compare(sync_profiles[0]));
695c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
697c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ProfileSyncServiceAutofillTest, HasNativeWithDuplicatesEmptySync) {
698c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // There is buggy autofill code that allows duplicate name/value
699c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // pairs to exist in the database with separate pair_ids.
700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<AutofillEntry> entries;
701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  entries.push_back(MakeAutofillEntry("foo", "bar", 1));
702c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  entries.push_back(MakeAutofillEntry("dup", "", 2));
703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  entries.push_back(MakeAutofillEntry("dup", "", 3));
704ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).
705c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      WillOnce(DoAll(SetArgumentPointee<0>(entries), Return(true)));
706ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).WillOnce(Return(true));
707c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SetIdleChangeProcessorExpectations();
708c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CreateRootTask task(this, syncable::AUTOFILL);
709c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_CALL(*personal_data_manager_, Refresh());
7103f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  StartSyncService(&task, false, syncable::AUTOFILL);
711c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(task.success());
712c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<AutofillEntry> sync_entries;
713ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<AutofillProfile> sync_profiles;
714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles));
715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(2U, sync_entries.size());
716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
717c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
718c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncNoMerge) {
719c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AutofillEntry native_entry(MakeAutofillEntry("native", "entry", 1));
720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AutofillEntry sync_entry(MakeAutofillEntry("sync", "entry", 2));
721c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
722c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<AutofillEntry> native_entries;
723c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  native_entries.push_back(native_entry);
724c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
725ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).
726c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      WillOnce(DoAll(SetArgumentPointee<0>(native_entries), Return(true)));
7273f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
728ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).WillOnce(Return(true));
7293f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
730c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<AutofillEntry> sync_entries;
731c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  sync_entries.push_back(sync_entry);
732c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7333f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  AddAutofillTask<AutofillEntry> task(this, sync_entries);
7343f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
735ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(autofill_table_, UpdateAutofillEntries(ElementsAre(sync_entry))).
736c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      WillOnce(Return(true));
7373f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
738c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_CALL(*personal_data_manager_, Refresh());
7393f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  StartSyncService(&task, false, syncable::AUTOFILL);
740c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(task.success());
741c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
742c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::set<AutofillEntry> expected_entries;
743c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  expected_entries.insert(native_entry);
744c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  expected_entries.insert(sync_entry);
745c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
746c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<AutofillEntry> new_sync_entries;
747ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<AutofillProfile> new_sync_profiles;
748c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries,
749c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                           &new_sync_profiles));
750c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::set<AutofillEntry> new_sync_entries_set(new_sync_entries.begin(),
751c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                               new_sync_entries.end());
752c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
753c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(expected_entries == new_sync_entries_set);
754c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
755c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
756c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncMergeEntry) {
757c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AutofillEntry native_entry(MakeAutofillEntry("merge", "entry", 1));
758c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AutofillEntry sync_entry(MakeAutofillEntry("merge", "entry", 2));
759c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AutofillEntry merged_entry(MakeAutofillEntry("merge", "entry", 1, 2));
760c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
761c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<AutofillEntry> native_entries;
762c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  native_entries.push_back(native_entry);
763ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).
764c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      WillOnce(DoAll(SetArgumentPointee<0>(native_entries), Return(true)));
765ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).WillOnce(Return(true));
766c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
767c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<AutofillEntry> sync_entries;
768c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  sync_entries.push_back(sync_entry);
7693f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  AddAutofillTask<AutofillEntry> task(this, sync_entries);
770c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
771ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(autofill_table_,
772ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      UpdateAutofillEntries(ElementsAre(merged_entry))).WillOnce(Return(true));
773c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_CALL(*personal_data_manager_, Refresh());
7743f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  StartSyncService(&task, false, syncable::AUTOFILL);
775c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(task.success());
776c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
777c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<AutofillEntry> new_sync_entries;
778ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<AutofillProfile> new_sync_profiles;
779c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries,
780c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                           &new_sync_profiles));
781c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(1U, new_sync_entries.size());
782c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(merged_entry == new_sync_entries[0]);
783c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
784c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
785c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncMergeProfile) {
786ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AutofillProfile sync_profile;
7873f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  autofill_test::SetProfileInfoWithGuid(&sync_profile,
788dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing",
7893f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      "Mitchell", "Morrison",
790c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
791c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "91601", "US", "12345678910", "01987654321");
792c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
793ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AutofillProfile* native_profile = new AutofillProfile;
7943f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  autofill_test::SetProfileInfoWithGuid(native_profile,
795dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing", "Alicia", "Saenz",
796c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
797c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "32801", "US", "19482937549", "13502849239");
798c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
799ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<AutofillProfile*> native_profiles;
800c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  native_profiles.push_back(native_profile);
801ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).
802c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      WillOnce(DoAll(SetArgumentPointee<0>(native_profiles), Return(true)));
803c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
804ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<AutofillProfile> sync_profiles;
805c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  sync_profiles.push_back(sync_profile);
806ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AddAutofillTask<AutofillProfile> task(this, sync_profiles);
807c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
808ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(autofill_table_, UpdateAutofillProfile(_)).
809c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      WillOnce(Return(true));
810c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_CALL(*personal_data_manager_, Refresh());
8113f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  StartSyncService(&task, false, syncable::AUTOFILL_PROFILE);
812c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(task.success());
813c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
814ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<AutofillProfile> new_sync_profiles;
8153f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(
8163f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      &new_sync_profiles));
817c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(1U, new_sync_profiles.size());
818513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  EXPECT_EQ(0, sync_profile.Compare(new_sync_profiles[0]));
819c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
820c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
8213f50c38dc070f4bb515c1b64450dae14f316474eKristian MonsenTEST_F(ProfileSyncServiceAutofillTest, MergeProfileWithDifferentGuid) {
822ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AutofillProfile sync_profile;
8233f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
8243f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  autofill_test::SetProfileInfoWithGuid(&sync_profile,
825dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing",
8263f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      "Mitchell", "Morrison",
8273f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
8283f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      "91601", "US", "12345678910", "01987654321");
8293f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
830dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  std::string native_guid = "EDC609ED-7EEE-4F27-B00C-423242A9C44B";
831ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AutofillProfile* native_profile = new AutofillProfile;
8323f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  autofill_test::SetProfileInfoWithGuid(native_profile,
8333f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      native_guid.c_str(), "Billing",
8343f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      "Mitchell", "Morrison",
8353f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
8363f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      "91601", "US", "12345678910", "01987654321");
8373f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
838ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<AutofillProfile*> native_profiles;
8393f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  native_profiles.push_back(native_profile);
840ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).
8413f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      WillOnce(DoAll(SetArgumentPointee<0>(native_profiles), Return(true)));
8423f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
843ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<AutofillProfile> sync_profiles;
8443f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  sync_profiles.push_back(sync_profile);
845ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AddAutofillTask<AutofillProfile> task(this, sync_profiles);
8463f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
847ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(autofill_table_, AddAutofillProfile(_)).
8483f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      WillOnce(Return(true));
849ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(autofill_table_, RemoveAutofillProfile(native_guid)).
8503f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      WillOnce(Return(true));
8513f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  EXPECT_CALL(*personal_data_manager_, Refresh());
8523f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  StartSyncService(&task, false, syncable::AUTOFILL_PROFILE);
8533f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  ASSERT_TRUE(task.success());
8543f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
855ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<AutofillProfile> new_sync_profiles;
8563f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(
8573f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      &new_sync_profiles));
8583f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  ASSERT_EQ(1U, new_sync_profiles.size());
8593f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  EXPECT_EQ(0, sync_profile.Compare(new_sync_profiles[0]));
8603f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  EXPECT_EQ(sync_profile.guid(), new_sync_profiles[0].guid());
8613f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
8623f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
863c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeAddEntry) {
864ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).WillOnce(Return(true));
865ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).WillOnce(Return(true));
866c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_CALL(*personal_data_manager_, Refresh());
867c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SetIdleChangeProcessorExpectations();
868c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CreateRootTask task(this, syncable::AUTOFILL);
8693f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  StartSyncService(&task, false, syncable::AUTOFILL);
870c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(task.success());
871c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
872c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AutofillEntry added_entry(MakeAutofillEntry("added", "entry", 1));
873c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<base::Time> timestamps(added_entry.timestamps());
874c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
875ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(autofill_table_, GetAutofillTimestamps(_, _, _)).
876c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      WillOnce(DoAll(SetArgumentPointee<2>(timestamps), Return(true)));
877c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
878c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AutofillChangeList changes;
879c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  changes.push_back(AutofillChange(AutofillChange::ADD, added_entry.key()));
880513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  scoped_refptr<ThreadNotifier> notifier(new ThreadNotifier(&db_thread_));
881c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  notifier->Notify(NotificationType::AUTOFILL_ENTRIES_CHANGED,
882c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   Source<WebDataService>(web_data_service_.get()),
883c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   Details<AutofillChangeList>(&changes));
884c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
885c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<AutofillEntry> new_sync_entries;
886ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<AutofillProfile> new_sync_profiles;
887c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries,
888c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                           &new_sync_profiles));
889c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(1U, new_sync_entries.size());
890c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(added_entry == new_sync_entries[0]);
891c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
892c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
893c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeAddProfile) {
894ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).WillOnce(Return(true));
895c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_CALL(*personal_data_manager_, Refresh());
896c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SetIdleChangeProcessorExpectations();
8973f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  CreateRootTask task(this, syncable::AUTOFILL_PROFILE);
8983f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  StartSyncService(&task, false, syncable::AUTOFILL_PROFILE);
899c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(task.success());
900c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
901ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AutofillProfile added_profile;
9023f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  autofill_test::SetProfileInfoWithGuid(&added_profile,
903dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      "D6ADA912-D374-4C0A-917D-F5C8EBE43011", "Josephine", "Alicia", "Saenz",
904c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
905c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "32801", "US", "19482937549", "13502849239");
906c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
907dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  AutofillProfileChange change(AutofillProfileChange::ADD,
9083f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      added_profile.guid(), &added_profile);
909513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  scoped_refptr<ThreadNotifier> notifier(new ThreadNotifier(&db_thread_));
910dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  notifier->Notify(NotificationType::AUTOFILL_PROFILE_CHANGED,
911c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   Source<WebDataService>(web_data_service_.get()),
912dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                   Details<AutofillProfileChange>(&change));
913c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
914ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<AutofillProfile> new_sync_profiles;
9153f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(
9163f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      &new_sync_profiles));
917c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(1U, new_sync_profiles.size());
918513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  EXPECT_EQ(0, added_profile.Compare(new_sync_profiles[0]));
919c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
920c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
921c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeUpdateEntry) {
922c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AutofillEntry original_entry(MakeAutofillEntry("my", "entry", 1));
923c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<AutofillEntry> original_entries;
924c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  original_entries.push_back(original_entry);
925c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
926ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).
927c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      WillOnce(DoAll(SetArgumentPointee<0>(original_entries), Return(true)));
928ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).WillOnce(Return(true));
929c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_CALL(*personal_data_manager_, Refresh());
930c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CreateRootTask task(this, syncable::AUTOFILL);
9313f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  StartSyncService(&task, false, syncable::AUTOFILL);
932c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(task.success());
933c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
934c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AutofillEntry updated_entry(MakeAutofillEntry("my", "entry", 1, 2));
935c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<base::Time> timestamps(updated_entry.timestamps());
936c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
937ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(autofill_table_, GetAutofillTimestamps(_, _, _)).
938c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      WillOnce(DoAll(SetArgumentPointee<2>(timestamps), Return(true)));
939c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
940c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AutofillChangeList changes;
941c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  changes.push_back(AutofillChange(AutofillChange::UPDATE,
942c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   updated_entry.key()));
943513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  scoped_refptr<ThreadNotifier> notifier(new ThreadNotifier(&db_thread_));
944c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  notifier->Notify(NotificationType::AUTOFILL_ENTRIES_CHANGED,
945c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   Source<WebDataService>(web_data_service_.get()),
946c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   Details<AutofillChangeList>(&changes));
947c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
948c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<AutofillEntry> new_sync_entries;
949ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<AutofillProfile> new_sync_profiles;
950c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries,
951c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                           &new_sync_profiles));
952c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(1U, new_sync_entries.size());
953c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(updated_entry == new_sync_entries[0]);
954c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
955c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
956c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
957c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeRemoveEntry) {
958c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AutofillEntry original_entry(MakeAutofillEntry("my", "entry", 1));
959c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<AutofillEntry> original_entries;
960c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  original_entries.push_back(original_entry);
961c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
962ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).
963c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      WillOnce(DoAll(SetArgumentPointee<0>(original_entries), Return(true)));
964ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).WillOnce(Return(true));
965c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_CALL(*personal_data_manager_, Refresh());
966c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CreateRootTask task(this, syncable::AUTOFILL);
9673f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  StartSyncService(&task, false, syncable::AUTOFILL);
968c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(task.success());
969c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
970c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AutofillChangeList changes;
971c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  changes.push_back(AutofillChange(AutofillChange::REMOVE,
972c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   original_entry.key()));
973513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  scoped_refptr<ThreadNotifier> notifier(new ThreadNotifier(&db_thread_));
974c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  notifier->Notify(NotificationType::AUTOFILL_ENTRIES_CHANGED,
975c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   Source<WebDataService>(web_data_service_.get()),
976c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   Details<AutofillChangeList>(&changes));
977c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
978c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<AutofillEntry> new_sync_entries;
979ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<AutofillProfile> new_sync_profiles;
980c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&new_sync_entries,
981c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                           &new_sync_profiles));
982c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(0U, new_sync_entries.size());
983c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
984c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
985c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeRemoveProfile) {
986ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AutofillProfile sync_profile;
9873f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  autofill_test::SetProfileInfoWithGuid(&sync_profile,
988dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      "3BA5FA1B-1EC4-4BB3-9B57-EC92BE3C1A09", "Josephine", "Alicia", "Saenz",
989c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
990c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "32801", "US", "19482937549", "13502849239");
991ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AutofillProfile* native_profile = new AutofillProfile;
9923f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  autofill_test::SetProfileInfoWithGuid(native_profile,
993dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      "3BA5FA1B-1EC4-4BB3-9B57-EC92BE3C1A09", "Josephine", "Alicia", "Saenz",
994c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL",
995c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "32801", "US", "19482937549", "13502849239");
996c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
997ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<AutofillProfile*> native_profiles;
998c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  native_profiles.push_back(native_profile);
999ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).
1000c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      WillOnce(DoAll(SetArgumentPointee<0>(native_profiles), Return(true)));
1001c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1002ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<AutofillProfile> sync_profiles;
1003c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  sync_profiles.push_back(sync_profile);
1004ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AddAutofillTask<AutofillProfile> task(this, sync_profiles);
1005c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_CALL(*personal_data_manager_, Refresh());
10063f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  StartSyncService(&task, false, syncable::AUTOFILL_PROFILE);
1007c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(task.success());
1008c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1009dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  AutofillProfileChange change(AutofillProfileChange::REMOVE,
10103f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                               sync_profile.guid(), NULL);
1011513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  scoped_refptr<ThreadNotifier> notifier(new ThreadNotifier(&db_thread_));
1012dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  notifier->Notify(NotificationType::AUTOFILL_PROFILE_CHANGED,
1013c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   Source<WebDataService>(web_data_service_.get()),
1014dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                   Details<AutofillProfileChange>(&change));
1015c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1016ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<AutofillProfile> new_sync_profiles;
10173f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(
10183f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      &new_sync_profiles));
10193f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  ASSERT_EQ(0U, new_sync_profiles.size());
1020c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1021c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1022c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeError) {
1023ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).WillOnce(Return(true));
1024ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).WillOnce(Return(true));
1025c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_CALL(*personal_data_manager_, Refresh());
1026c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CreateRootTask task(this, syncable::AUTOFILL);
10273f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  StartSyncService(&task, false, syncable::AUTOFILL);
1028c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(task.success());
1029c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1030c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Inject an evil entry into the sync db to conflict with the same
1031c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // entry added by the user.
1032c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AutofillEntry evil_entry(MakeAutofillEntry("evil", "entry", 1));
1033c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(AddAutofillSyncNode(evil_entry));
1034c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1035c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AutofillChangeList changes;
1036c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  changes.push_back(AutofillChange(AutofillChange::ADD,
1037c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   evil_entry.key()));
1038513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  scoped_refptr<ThreadNotifier> notifier(new ThreadNotifier(&db_thread_));
1039c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  notifier->Notify(NotificationType::AUTOFILL_ENTRIES_CHANGED,
1040c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   Source<WebDataService>(web_data_service_.get()),
1041c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   Details<AutofillChangeList>(&changes));
1042c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1043c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Wait for the PPS to shut everything down and signal us.
1044c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ProfileSyncServiceObserverMock observer;
1045c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service_->AddObserver(&observer);
1046c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_CALL(observer, OnStateChanged()).WillOnce(QuitUIMessageLoop());
1047c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->Run();
1048c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(service_->unrecoverable_error_detected());
1049c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1050c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Ensure future autofill notifications don't crash.
1051c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  notifier->Notify(NotificationType::AUTOFILL_ENTRIES_CHANGED,
1052c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   Source<WebDataService>(web_data_service_.get()),
1053c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   Details<AutofillChangeList>(&changes));
1054c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
10553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1056731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Crashy, http://crbug.com/57884
1057731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(ProfileSyncServiceAutofillTest, DISABLED_ServerChangeRace) {
1058ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(autofill_table_, GetAllAutofillEntries(_)).WillOnce(Return(true));
1059ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(autofill_table_, GetAutofillProfiles(_)).WillOnce(Return(true));
1060ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(autofill_table_, UpdateAutofillEntries(_)).
10613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      WillRepeatedly(Return(true));
10623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_CALL(*personal_data_manager_, Refresh()).Times(3);
10633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CreateRootTask task(this, syncable::AUTOFILL);
10643f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  StartSyncService(&task, false, syncable::AUTOFILL);
10653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_TRUE(task.success());
10663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
10673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // (true, false) means we have to reset after |Signal|, init to unsignaled.
10683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_ptr<WaitableEvent> wait_for_start(new WaitableEvent(true, false));
10693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_ptr<WaitableEvent> wait_for_syncapi(new WaitableEvent(true, false));
1070513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  scoped_refptr<FakeServerUpdater> updater(new FakeServerUpdater(
1071513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      service_.get(), &wait_for_start, &wait_for_syncapi));
10723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
10733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // This server side update will stall waiting for CommitWaiter.
10743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  updater->CreateNewEntry(MakeAutofillEntry("server", "entry", 1));
10753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  wait_for_start->Wait();
10763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
10773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  AutofillEntry syncapi_entry(MakeAutofillEntry("syncapi", "entry", 2));
10783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_TRUE(AddAutofillSyncNode(syncapi_entry));
1079731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  VLOG(1) << "Syncapi update finished.";
10803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
10813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // If we reach here, it means syncapi succeeded and we didn't deadlock. Yay!
10823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Signal FakeServerUpdater that it can complete.
10833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  wait_for_syncapi->Signal();
10843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
10853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Make another entry to ensure nothing broke afterwards and wait for finish
10863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // to clean up.
10873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  updater->CreateNewEntryAndWait(MakeAutofillEntry("server2", "entry2", 3));
10883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
10893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::vector<AutofillEntry> sync_entries;
1090ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<AutofillProfile> sync_profiles;
10913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles));
10923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(3U, sync_entries.size());
10933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(0U, sync_profiles.size());
10943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  for (size_t i = 0; i < sync_entries.size(); i++) {
1095731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    VLOG(1) << "Entry " << i << ": " << sync_entries[i].key().name()
1096731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick            << ", " << sync_entries[i].key().value();
10973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
10983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
1099