1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/browser/sync/test/integration/autofill_helper.h" 6 7 #include "chrome/browser/autofill/personal_data_manager_factory.h" 8 #include "chrome/browser/chrome_notification_types.h" 9 #include "chrome/browser/profiles/profile.h" 10 #include "chrome/browser/sync/profile_sync_service.h" 11 #include "chrome/browser/sync/profile_sync_test_util.h" 12 #include "chrome/browser/sync/test/integration/sync_datatype_helper.h" 13 #include "chrome/browser/sync/test/integration/sync_test.h" 14 #include "chrome/browser/webdata/web_data_service_factory.h" 15 #include "components/autofill/core/browser/autofill_profile.h" 16 #include "components/autofill/core/browser/autofill_test_utils.h" 17 #include "components/autofill/core/browser/autofill_type.h" 18 #include "components/autofill/core/browser/personal_data_manager.h" 19 #include "components/autofill/core/browser/personal_data_manager_observer.h" 20 #include "components/autofill/core/browser/webdata/autofill_entry.h" 21 #include "components/autofill/core/browser/webdata/autofill_table.h" 22 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h" 23 #include "components/autofill/core/common/form_field_data.h" 24 #include "components/webdata/common/web_database.h" 25 26 using autofill::AutofillChangeList; 27 using autofill::AutofillEntry; 28 using autofill::AutofillKey; 29 using autofill::AutofillProfile; 30 using autofill::AutofillTable; 31 using autofill::AutofillType; 32 using autofill::AutofillWebDataService; 33 using autofill::AutofillWebDataServiceObserverOnDBThread; 34 using autofill::CreditCard; 35 using autofill::FormFieldData; 36 using autofill::PersonalDataManager; 37 using autofill::PersonalDataManagerObserver; 38 using base::WaitableEvent; 39 using content::BrowserThread; 40 using sync_datatype_helper::test; 41 using testing::_; 42 43 namespace { 44 45 ACTION_P(SignalEvent, event) { 46 event->Signal(); 47 } 48 49 class MockWebDataServiceObserver 50 : public AutofillWebDataServiceObserverOnDBThread { 51 public: 52 MOCK_METHOD1(AutofillEntriesChanged, 53 void(const AutofillChangeList& changes)); 54 }; 55 56 class MockPersonalDataManagerObserver : public PersonalDataManagerObserver { 57 public: 58 MOCK_METHOD0(OnPersonalDataChanged, void()); 59 }; 60 61 void RunOnDBThreadAndSignal(base::Closure task, 62 base::WaitableEvent* done_event) { 63 if (!task.is_null()) { 64 task.Run(); 65 } 66 done_event->Signal(); 67 } 68 69 void RunOnDBThreadAndBlock(base::Closure task) { 70 WaitableEvent done_event(false, false); 71 BrowserThread::PostTask(BrowserThread::DB, 72 FROM_HERE, 73 Bind(&RunOnDBThreadAndSignal, task, &done_event)); 74 done_event.Wait(); 75 } 76 77 void RemoveKeyDontBlockForSync(int profile, const AutofillKey& key) { 78 WaitableEvent done_event(false, false); 79 80 MockWebDataServiceObserver mock_observer; 81 EXPECT_CALL(mock_observer, AutofillEntriesChanged(_)) 82 .WillOnce(SignalEvent(&done_event)); 83 84 scoped_refptr<AutofillWebDataService> wds = 85 autofill_helper::GetWebDataService(profile); 86 87 void(AutofillWebDataService::*add_observer_func)( 88 AutofillWebDataServiceObserverOnDBThread*) = 89 &AutofillWebDataService::AddObserver; 90 RunOnDBThreadAndBlock(Bind(add_observer_func, wds, &mock_observer)); 91 92 wds->RemoveFormValueForElementName(key.name(), key.value()); 93 done_event.Wait(); 94 95 void(AutofillWebDataService::*remove_observer_func)( 96 AutofillWebDataServiceObserverOnDBThread*) = 97 &AutofillWebDataService::RemoveObserver; 98 RunOnDBThreadAndBlock(Bind(remove_observer_func, wds, &mock_observer)); 99 } 100 101 void GetAllAutofillEntriesOnDBThread(AutofillWebDataService* wds, 102 std::vector<AutofillEntry>* entries) { 103 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 104 AutofillTable::FromWebDatabase( 105 wds->GetDatabase())->GetAllAutofillEntries(entries); 106 } 107 108 std::vector<AutofillEntry> GetAllAutofillEntries(AutofillWebDataService* wds) { 109 std::vector<AutofillEntry> entries; 110 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 111 RunOnDBThreadAndBlock(Bind(&GetAllAutofillEntriesOnDBThread, 112 Unretained(wds), 113 &entries)); 114 return entries; 115 } 116 117 // UI thread returns from the update operations on the DB thread and schedules 118 // the sync. This function blocks until after this scheduled sync is complete by 119 // scheduling additional empty task on DB Thread. Call after AddKeys/RemoveKey. 120 void BlockForPendingDBThreadTasks() { 121 // The order of the notifications is undefined, so sync change sometimes is 122 // posted after the notification for observer_helper. Post new task to db 123 // thread that guaranteed to be after sync and would be blocking until 124 // completion. 125 RunOnDBThreadAndBlock(base::Closure()); 126 } 127 128 } // namespace 129 130 namespace autofill_helper { 131 132 AutofillProfile CreateAutofillProfile(ProfileType type) { 133 AutofillProfile profile; 134 switch (type) { 135 case PROFILE_MARION: 136 autofill::test::SetProfileInfoWithGuid(&profile, 137 "C837507A-6C3B-4872-AC14-5113F157D668", 138 "Marion", "Mitchell", "Morrison", 139 "johnwayne (at) me.xyz", "Fox", 140 "123 Zoo St.", "unit 5", "Hollywood", "CA", 141 "91601", "US", "12345678910"); 142 break; 143 case PROFILE_HOMER: 144 autofill::test::SetProfileInfoWithGuid(&profile, 145 "137DE1C3-6A30-4571-AC86-109B1ECFBE7F", 146 "Homer", "J.", "Simpson", 147 "homer (at) abc.com", "SNPP", 148 "1 Main St", "PO Box 1", "Springfield", "MA", 149 "94101", "US", "14155551212"); 150 break; 151 case PROFILE_FRASIER: 152 autofill::test::SetProfileInfoWithGuid(&profile, 153 "9A5E6872-6198-4688-BF75-0016E781BB0A", 154 "Frasier", "Winslow", "Crane", 155 "", "randomness", "", "Apt. 4", "Seattle", "WA", 156 "99121", "US", "0000000000"); 157 break; 158 case PROFILE_NULL: 159 autofill::test::SetProfileInfoWithGuid(&profile, 160 "FE461507-7E13-4198-8E66-74C7DB6D8322", 161 "", "", "", "", "", "", "", "", "", "", "", ""); 162 break; 163 } 164 return profile; 165 } 166 167 scoped_refptr<AutofillWebDataService> GetWebDataService(int index) { 168 return WebDataServiceFactory::GetAutofillWebDataForProfile( 169 test()->GetProfile(index), Profile::EXPLICIT_ACCESS); 170 } 171 172 PersonalDataManager* GetPersonalDataManager(int index) { 173 return autofill::PersonalDataManagerFactory::GetForProfile( 174 test()->GetProfile(index)); 175 } 176 177 void AddKeys(int profile, const std::set<AutofillKey>& keys) { 178 std::vector<FormFieldData> form_fields; 179 for (std::set<AutofillKey>::const_iterator i = keys.begin(); 180 i != keys.end(); 181 ++i) { 182 FormFieldData field; 183 field.name = i->name(); 184 field.value = i->value(); 185 form_fields.push_back(field); 186 } 187 188 WaitableEvent done_event(false, false); 189 MockWebDataServiceObserver mock_observer; 190 EXPECT_CALL(mock_observer, AutofillEntriesChanged(_)) 191 .WillOnce(SignalEvent(&done_event)); 192 193 scoped_refptr<AutofillWebDataService> wds = GetWebDataService(profile); 194 195 void(AutofillWebDataService::*add_observer_func)( 196 AutofillWebDataServiceObserverOnDBThread*) = 197 &AutofillWebDataService::AddObserver; 198 RunOnDBThreadAndBlock(Bind(add_observer_func, wds, &mock_observer)); 199 200 wds->AddFormFields(form_fields); 201 done_event.Wait(); 202 BlockForPendingDBThreadTasks(); 203 204 void(AutofillWebDataService::*remove_observer_func)( 205 AutofillWebDataServiceObserverOnDBThread*) = 206 &AutofillWebDataService::RemoveObserver; 207 RunOnDBThreadAndBlock(Bind(remove_observer_func, wds, &mock_observer)); 208 } 209 210 void RemoveKey(int profile, const AutofillKey& key) { 211 RemoveKeyDontBlockForSync(profile, key); 212 BlockForPendingDBThreadTasks(); 213 } 214 215 void RemoveKeys(int profile) { 216 std::set<AutofillEntry> keys = GetAllKeys(profile); 217 for (std::set<AutofillEntry>::const_iterator it = keys.begin(); 218 it != keys.end(); ++it) { 219 RemoveKeyDontBlockForSync(profile, it->key()); 220 } 221 BlockForPendingDBThreadTasks(); 222 } 223 224 std::set<AutofillEntry> GetAllKeys(int profile) { 225 scoped_refptr<AutofillWebDataService> wds = GetWebDataService(profile); 226 std::vector<AutofillEntry> all_entries = GetAllAutofillEntries(wds.get()); 227 std::set<AutofillEntry> all_keys; 228 for (std::vector<AutofillEntry>::const_iterator it = all_entries.begin(); 229 it != all_entries.end(); ++it) { 230 all_keys.insert(*it); 231 } 232 return all_keys; 233 } 234 235 bool KeysMatch(int profile_a, int profile_b) { 236 return GetAllKeys(profile_a) == GetAllKeys(profile_b); 237 } 238 239 void SetProfiles(int profile, std::vector<AutofillProfile>* autofill_profiles) { 240 MockPersonalDataManagerObserver observer; 241 EXPECT_CALL(observer, OnPersonalDataChanged()). 242 WillOnce(QuitUIMessageLoop()); 243 PersonalDataManager* pdm = GetPersonalDataManager(profile); 244 pdm->AddObserver(&observer); 245 pdm->SetProfiles(autofill_profiles); 246 base::MessageLoop::current()->Run(); 247 pdm->RemoveObserver(&observer); 248 } 249 250 void SetCreditCards(int profile, std::vector<CreditCard>* credit_cards) { 251 MockPersonalDataManagerObserver observer; 252 EXPECT_CALL(observer, OnPersonalDataChanged()). 253 WillOnce(QuitUIMessageLoop()); 254 PersonalDataManager* pdm = GetPersonalDataManager(profile); 255 pdm->AddObserver(&observer); 256 pdm->SetCreditCards(credit_cards); 257 base::MessageLoop::current()->Run(); 258 pdm->RemoveObserver(&observer); 259 } 260 261 void AddProfile(int profile, const AutofillProfile& autofill_profile) { 262 const std::vector<AutofillProfile*>& all_profiles = GetAllProfiles(profile); 263 std::vector<AutofillProfile> autofill_profiles; 264 for (size_t i = 0; i < all_profiles.size(); ++i) 265 autofill_profiles.push_back(*all_profiles[i]); 266 autofill_profiles.push_back(autofill_profile); 267 autofill_helper::SetProfiles(profile, &autofill_profiles); 268 } 269 270 void RemoveProfile(int profile, const std::string& guid) { 271 const std::vector<AutofillProfile*>& all_profiles = GetAllProfiles(profile); 272 std::vector<AutofillProfile> autofill_profiles; 273 for (size_t i = 0; i < all_profiles.size(); ++i) { 274 if (all_profiles[i]->guid() != guid) 275 autofill_profiles.push_back(*all_profiles[i]); 276 } 277 autofill_helper::SetProfiles(profile, &autofill_profiles); 278 } 279 280 void UpdateProfile(int profile, 281 const std::string& guid, 282 const AutofillType& type, 283 const base::string16& value) { 284 const std::vector<AutofillProfile*>& all_profiles = GetAllProfiles(profile); 285 std::vector<AutofillProfile> profiles; 286 for (size_t i = 0; i < all_profiles.size(); ++i) { 287 profiles.push_back(*all_profiles[i]); 288 if (all_profiles[i]->guid() == guid) 289 profiles.back().SetRawInfo(type.GetStorableType(), value); 290 } 291 autofill_helper::SetProfiles(profile, &profiles); 292 } 293 294 const std::vector<AutofillProfile*>& GetAllProfiles( 295 int profile) { 296 MockPersonalDataManagerObserver observer; 297 EXPECT_CALL(observer, OnPersonalDataChanged()). 298 WillOnce(QuitUIMessageLoop()); 299 PersonalDataManager* pdm = GetPersonalDataManager(profile); 300 pdm->AddObserver(&observer); 301 pdm->Refresh(); 302 base::MessageLoop::current()->Run(); 303 pdm->RemoveObserver(&observer); 304 return pdm->web_profiles(); 305 } 306 307 int GetProfileCount(int profile) { 308 return GetAllProfiles(profile).size(); 309 } 310 311 int GetKeyCount(int profile) { 312 return GetAllKeys(profile).size(); 313 } 314 315 bool ProfilesMatch(int profile_a, int profile_b) { 316 const std::vector<AutofillProfile*>& autofill_profiles_a = 317 GetAllProfiles(profile_a); 318 std::map<std::string, AutofillProfile> autofill_profiles_a_map; 319 for (size_t i = 0; i < autofill_profiles_a.size(); ++i) { 320 const AutofillProfile* p = autofill_profiles_a[i]; 321 autofill_profiles_a_map[p->guid()] = *p; 322 } 323 324 const std::vector<AutofillProfile*>& autofill_profiles_b = 325 GetAllProfiles(profile_b); 326 for (size_t i = 0; i < autofill_profiles_b.size(); ++i) { 327 const AutofillProfile* p = autofill_profiles_b[i]; 328 if (!autofill_profiles_a_map.count(p->guid())) { 329 LOG(ERROR) << "GUID " << p->guid() << " not found in profile " 330 << profile_b << "."; 331 return false; 332 } 333 AutofillProfile* expected_profile = &autofill_profiles_a_map[p->guid()]; 334 expected_profile->set_guid(p->guid()); 335 if (*expected_profile != *p) { 336 LOG(ERROR) << "Mismatch in profile with GUID " << p->guid() << "."; 337 return false; 338 } 339 autofill_profiles_a_map.erase(p->guid()); 340 } 341 342 if (autofill_profiles_a_map.size()) { 343 LOG(ERROR) << "Entries present in Profile " << profile_a 344 << " but not in " << profile_b << "."; 345 return false; 346 } 347 return true; 348 } 349 350 bool AllProfilesMatch() { 351 for (int i = 1; i < test()->num_clients(); ++i) { 352 if (!ProfilesMatch(0, i)) { 353 LOG(ERROR) << "Profile " << i << "does not contain the same autofill " 354 "profiles as profile 0."; 355 return false; 356 } 357 } 358 return true; 359 } 360 361 } // namespace autofill_helper 362