BookmarkManager: Fix 'new folder text field size changes on clicking it' issue.
[chromium-blink-merge.git] / chrome / browser / sync / test / integration / autofill_helper.cc
blob626f749bc5e302a801787aa29157d269534b68c1
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.
5 #include "chrome/browser/sync/test/integration/autofill_helper.h"
7 #include "base/guid.h"
8 #include "chrome/browser/autofill/personal_data_manager_factory.h"
9 #include "chrome/browser/chrome_notification_types.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/sync/profile_sync_service.h"
12 #include "chrome/browser/sync/profile_sync_test_util.h"
13 #include "chrome/browser/sync/test/integration/multi_client_status_change_checker.h"
14 #include "chrome/browser/sync/test/integration/sync_datatype_helper.h"
15 #include "chrome/browser/sync/test/integration/sync_test.h"
16 #include "chrome/browser/web_data_service_factory.h"
17 #include "components/autofill/core/browser/autofill_profile.h"
18 #include "components/autofill/core/browser/autofill_test_utils.h"
19 #include "components/autofill/core/browser/autofill_type.h"
20 #include "components/autofill/core/browser/personal_data_manager.h"
21 #include "components/autofill/core/browser/personal_data_manager_observer.h"
22 #include "components/autofill/core/browser/webdata/autofill_entry.h"
23 #include "components/autofill/core/browser/webdata/autofill_table.h"
24 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
25 #include "components/autofill/core/common/form_field_data.h"
26 #include "components/webdata/common/web_database.h"
28 using autofill::AutofillChangeList;
29 using autofill::AutofillEntry;
30 using autofill::AutofillKey;
31 using autofill::AutofillProfile;
32 using autofill::AutofillTable;
33 using autofill::AutofillType;
34 using autofill::AutofillWebDataService;
35 using autofill::AutofillWebDataServiceObserverOnDBThread;
36 using autofill::CreditCard;
37 using autofill::FormFieldData;
38 using autofill::PersonalDataManager;
39 using autofill::PersonalDataManagerObserver;
40 using base::WaitableEvent;
41 using content::BrowserThread;
42 using sync_datatype_helper::test;
43 using testing::_;
45 namespace {
47 ACTION_P(SignalEvent, event) {
48 event->Signal();
51 class MockWebDataServiceObserver
52 : public AutofillWebDataServiceObserverOnDBThread {
53 public:
54 MOCK_METHOD1(AutofillEntriesChanged,
55 void(const AutofillChangeList& changes));
58 class MockPersonalDataManagerObserver : public PersonalDataManagerObserver {
59 public:
60 MOCK_METHOD0(OnPersonalDataChanged, void());
63 void RunOnDBThreadAndSignal(base::Closure task,
64 base::WaitableEvent* done_event) {
65 if (!task.is_null()) {
66 task.Run();
68 done_event->Signal();
71 void RunOnDBThreadAndBlock(base::Closure task) {
72 WaitableEvent done_event(false, false);
73 BrowserThread::PostTask(BrowserThread::DB,
74 FROM_HERE,
75 Bind(&RunOnDBThreadAndSignal, task, &done_event));
76 done_event.Wait();
79 void RemoveKeyDontBlockForSync(int profile, const AutofillKey& key) {
80 WaitableEvent done_event(false, false);
82 MockWebDataServiceObserver mock_observer;
83 EXPECT_CALL(mock_observer, AutofillEntriesChanged(_))
84 .WillOnce(SignalEvent(&done_event));
86 scoped_refptr<AutofillWebDataService> wds =
87 autofill_helper::GetWebDataService(profile);
89 void(AutofillWebDataService::*add_observer_func)(
90 AutofillWebDataServiceObserverOnDBThread*) =
91 &AutofillWebDataService::AddObserver;
92 RunOnDBThreadAndBlock(Bind(add_observer_func, wds, &mock_observer));
94 wds->RemoveFormValueForElementName(key.name(), key.value());
95 done_event.Wait();
97 void(AutofillWebDataService::*remove_observer_func)(
98 AutofillWebDataServiceObserverOnDBThread*) =
99 &AutofillWebDataService::RemoveObserver;
100 RunOnDBThreadAndBlock(Bind(remove_observer_func, wds, &mock_observer));
103 void GetAllAutofillEntriesOnDBThread(AutofillWebDataService* wds,
104 std::vector<AutofillEntry>* entries) {
105 DCHECK_CURRENTLY_ON(BrowserThread::DB);
106 AutofillTable::FromWebDatabase(
107 wds->GetDatabase())->GetAllAutofillEntries(entries);
110 std::vector<AutofillEntry> GetAllAutofillEntries(AutofillWebDataService* wds) {
111 std::vector<AutofillEntry> entries;
112 DCHECK_CURRENTLY_ON(BrowserThread::UI);
113 RunOnDBThreadAndBlock(Bind(&GetAllAutofillEntriesOnDBThread,
114 Unretained(wds),
115 &entries));
116 return entries;
119 // UI thread returns from the update operations on the DB thread and schedules
120 // the sync. This function blocks until after this scheduled sync is complete by
121 // scheduling additional empty task on DB Thread. Call after AddKeys/RemoveKey.
122 void BlockForPendingDBThreadTasks() {
123 // The order of the notifications is undefined, so sync change sometimes is
124 // posted after the notification for observer_helper. Post new task to db
125 // thread that guaranteed to be after sync and would be blocking until
126 // completion.
127 RunOnDBThreadAndBlock(base::Closure());
130 } // namespace
132 namespace autofill_helper {
134 AutofillProfile CreateAutofillProfile(ProfileType type) {
135 AutofillProfile profile;
136 switch (type) {
137 case PROFILE_MARION:
138 autofill::test::SetProfileInfoWithGuid(&profile,
139 "C837507A-6C3B-4872-AC14-5113F157D668",
140 "Marion", "Mitchell", "Morrison",
141 "johnwayne@me.xyz", "Fox",
142 "123 Zoo St.", "unit 5", "Hollywood", "CA",
143 "91601", "US", "12345678910");
144 break;
145 case PROFILE_HOMER:
146 autofill::test::SetProfileInfoWithGuid(&profile,
147 "137DE1C3-6A30-4571-AC86-109B1ECFBE7F",
148 "Homer", "J.", "Simpson",
149 "homer@abc.com", "SNPP",
150 "742 Evergreen Terrace", "PO Box 1", "Springfield", "MA",
151 "94101", "US", "14155551212");
152 break;
153 case PROFILE_FRASIER:
154 autofill::test::SetProfileInfoWithGuid(&profile,
155 "9A5E6872-6198-4688-BF75-0016E781BB0A",
156 "Frasier", "Winslow", "Crane",
157 "", "randomness", "", "Apt. 4", "Seattle", "WA",
158 "99121", "US", "0000000000");
159 break;
160 case PROFILE_NULL:
161 autofill::test::SetProfileInfoWithGuid(&profile,
162 "FE461507-7E13-4198-8E66-74C7DB6D8322",
163 "", "", "", "", "", "", "", "", "", "", "", "");
164 break;
166 return profile;
169 AutofillProfile CreateUniqueAutofillProfile() {
170 AutofillProfile profile;
171 autofill::test::SetProfileInfoWithGuid(&profile,
172 base::GenerateGUID().c_str(),
173 "First", "Middle", "Last",
174 "email@domain.tld", "Company",
175 "123 Main St", "Apt 456", "Nowhere", "OK",
176 "73038", "US", "12345678910");
177 return profile;
180 scoped_refptr<AutofillWebDataService> GetWebDataService(int index) {
181 return WebDataServiceFactory::GetAutofillWebDataForProfile(
182 test()->GetProfile(index), ServiceAccessType::EXPLICIT_ACCESS);
185 PersonalDataManager* GetPersonalDataManager(int index) {
186 return autofill::PersonalDataManagerFactory::GetForProfile(
187 test()->GetProfile(index));
190 void AddKeys(int profile, const std::set<AutofillKey>& keys) {
191 std::vector<FormFieldData> form_fields;
192 for (std::set<AutofillKey>::const_iterator i = keys.begin();
193 i != keys.end();
194 ++i) {
195 FormFieldData field;
196 field.name = i->name();
197 field.value = i->value();
198 form_fields.push_back(field);
201 WaitableEvent done_event(false, false);
202 MockWebDataServiceObserver mock_observer;
203 EXPECT_CALL(mock_observer, AutofillEntriesChanged(_))
204 .WillOnce(SignalEvent(&done_event));
206 scoped_refptr<AutofillWebDataService> wds = GetWebDataService(profile);
208 void(AutofillWebDataService::*add_observer_func)(
209 AutofillWebDataServiceObserverOnDBThread*) =
210 &AutofillWebDataService::AddObserver;
211 RunOnDBThreadAndBlock(Bind(add_observer_func, wds, &mock_observer));
213 wds->AddFormFields(form_fields);
214 done_event.Wait();
215 BlockForPendingDBThreadTasks();
217 void(AutofillWebDataService::*remove_observer_func)(
218 AutofillWebDataServiceObserverOnDBThread*) =
219 &AutofillWebDataService::RemoveObserver;
220 RunOnDBThreadAndBlock(Bind(remove_observer_func, wds, &mock_observer));
223 void RemoveKey(int profile, const AutofillKey& key) {
224 RemoveKeyDontBlockForSync(profile, key);
225 BlockForPendingDBThreadTasks();
228 void RemoveKeys(int profile) {
229 std::set<AutofillEntry> keys = GetAllKeys(profile);
230 for (std::set<AutofillEntry>::const_iterator it = keys.begin();
231 it != keys.end(); ++it) {
232 RemoveKeyDontBlockForSync(profile, it->key());
234 BlockForPendingDBThreadTasks();
237 std::set<AutofillEntry> GetAllKeys(int profile) {
238 scoped_refptr<AutofillWebDataService> wds = GetWebDataService(profile);
239 std::vector<AutofillEntry> all_entries = GetAllAutofillEntries(wds.get());
240 std::set<AutofillEntry> all_keys;
241 for (std::vector<AutofillEntry>::const_iterator it = all_entries.begin();
242 it != all_entries.end(); ++it) {
243 all_keys.insert(*it);
245 return all_keys;
248 bool KeysMatch(int profile_a, int profile_b) {
249 return GetAllKeys(profile_a) == GetAllKeys(profile_b);
252 namespace {
254 class KeysMatchStatusChecker : public MultiClientStatusChangeChecker {
255 public:
256 KeysMatchStatusChecker(int profile_a, int profile_b);
257 ~KeysMatchStatusChecker() override;
259 bool IsExitConditionSatisfied() override;
260 std::string GetDebugMessage() const override;
262 private:
263 const int profile_a_;
264 const int profile_b_;
267 KeysMatchStatusChecker::KeysMatchStatusChecker(int profile_a, int profile_b)
268 : MultiClientStatusChangeChecker(
269 sync_datatype_helper::test()->GetSyncServices()),
270 profile_a_(profile_a),
271 profile_b_(profile_b) {
274 KeysMatchStatusChecker::~KeysMatchStatusChecker() {
277 bool KeysMatchStatusChecker::IsExitConditionSatisfied() {
278 return KeysMatch(profile_a_, profile_b_);
281 std::string KeysMatchStatusChecker::GetDebugMessage() const {
282 return "Waiting for matching autofill keys";
285 } // namespace
287 bool AwaitKeysMatch(int a, int b) {
288 KeysMatchStatusChecker checker(a, b);
289 checker.Wait();
290 return !checker.TimedOut();
293 void SetProfiles(int profile, std::vector<AutofillProfile>* autofill_profiles) {
294 MockPersonalDataManagerObserver observer;
295 EXPECT_CALL(observer, OnPersonalDataChanged()).
296 WillOnce(QuitUIMessageLoop());
297 PersonalDataManager* pdm = GetPersonalDataManager(profile);
298 pdm->AddObserver(&observer);
299 pdm->SetProfiles(autofill_profiles);
300 base::MessageLoop::current()->Run();
301 pdm->RemoveObserver(&observer);
304 void SetCreditCards(int profile, std::vector<CreditCard>* credit_cards) {
305 MockPersonalDataManagerObserver observer;
306 EXPECT_CALL(observer, OnPersonalDataChanged()).
307 WillOnce(QuitUIMessageLoop());
308 PersonalDataManager* pdm = GetPersonalDataManager(profile);
309 pdm->AddObserver(&observer);
310 pdm->SetCreditCards(credit_cards);
311 base::MessageLoop::current()->Run();
312 pdm->RemoveObserver(&observer);
315 void AddProfile(int profile, const AutofillProfile& autofill_profile) {
316 const std::vector<AutofillProfile*>& all_profiles = GetAllProfiles(profile);
317 std::vector<AutofillProfile> autofill_profiles;
318 for (size_t i = 0; i < all_profiles.size(); ++i)
319 autofill_profiles.push_back(*all_profiles[i]);
320 autofill_profiles.push_back(autofill_profile);
321 autofill_helper::SetProfiles(profile, &autofill_profiles);
324 void RemoveProfile(int profile, const std::string& guid) {
325 const std::vector<AutofillProfile*>& all_profiles = GetAllProfiles(profile);
326 std::vector<AutofillProfile> autofill_profiles;
327 for (size_t i = 0; i < all_profiles.size(); ++i) {
328 if (all_profiles[i]->guid() != guid)
329 autofill_profiles.push_back(*all_profiles[i]);
331 autofill_helper::SetProfiles(profile, &autofill_profiles);
334 void UpdateProfile(int profile,
335 const std::string& guid,
336 const AutofillType& type,
337 const base::string16& value) {
338 const std::vector<AutofillProfile*>& all_profiles = GetAllProfiles(profile);
339 std::vector<AutofillProfile> profiles;
340 for (size_t i = 0; i < all_profiles.size(); ++i) {
341 profiles.push_back(*all_profiles[i]);
342 if (all_profiles[i]->guid() == guid)
343 profiles.back().SetRawInfo(type.GetStorableType(), value);
345 autofill_helper::SetProfiles(profile, &profiles);
348 const std::vector<AutofillProfile*>& GetAllProfiles(
349 int profile) {
350 MockPersonalDataManagerObserver observer;
351 EXPECT_CALL(observer, OnPersonalDataChanged()).
352 WillOnce(QuitUIMessageLoop());
353 PersonalDataManager* pdm = GetPersonalDataManager(profile);
354 pdm->AddObserver(&observer);
355 pdm->Refresh();
356 base::MessageLoop::current()->Run();
357 pdm->RemoveObserver(&observer);
358 return pdm->web_profiles();
361 int GetProfileCount(int profile) {
362 return GetAllProfiles(profile).size();
365 int GetKeyCount(int profile) {
366 return GetAllKeys(profile).size();
369 namespace {
371 bool ProfilesMatchImpl(
372 int profile_a,
373 const std::vector<AutofillProfile*>& autofill_profiles_a,
374 int profile_b,
375 const std::vector<AutofillProfile*>& autofill_profiles_b) {
376 std::map<std::string, AutofillProfile> autofill_profiles_a_map;
377 for (size_t i = 0; i < autofill_profiles_a.size(); ++i) {
378 const AutofillProfile* p = autofill_profiles_a[i];
379 autofill_profiles_a_map[p->guid()] = *p;
382 for (size_t i = 0; i < autofill_profiles_b.size(); ++i) {
383 const AutofillProfile* p = autofill_profiles_b[i];
384 if (!autofill_profiles_a_map.count(p->guid())) {
385 DVLOG(1) << "GUID " << p->guid() << " not found in profile " << profile_b
386 << ".";
387 return false;
389 AutofillProfile* expected_profile = &autofill_profiles_a_map[p->guid()];
390 expected_profile->set_guid(p->guid());
391 if (*expected_profile != *p) {
392 DVLOG(1) << "Mismatch in profile with GUID " << p->guid() << ".";
393 return false;
395 autofill_profiles_a_map.erase(p->guid());
398 if (autofill_profiles_a_map.size()) {
399 DVLOG(1) << "Entries present in Profile " << profile_a << " but not in "
400 << profile_b << ".";
401 return false;
403 return true;
406 } // namespace
408 bool ProfilesMatch(int profile_a, int profile_b) {
409 const std::vector<AutofillProfile*>& autofill_profiles_a =
410 GetAllProfiles(profile_a);
411 const std::vector<AutofillProfile*>& autofill_profiles_b =
412 GetAllProfiles(profile_b);
413 return ProfilesMatchImpl(
414 profile_a, autofill_profiles_a, profile_b, autofill_profiles_b);
417 bool AllProfilesMatch() {
418 for (int i = 1; i < test()->num_clients(); ++i) {
419 if (!ProfilesMatch(0, i)) {
420 DVLOG(1) << "Profile " << i << "does not contain the same autofill "
421 "profiles as profile 0.";
422 return false;
425 return true;
428 namespace {
430 class ProfilesMatchStatusChecker : public StatusChangeChecker,
431 public PersonalDataManagerObserver {
432 public:
433 ProfilesMatchStatusChecker(int profile_a, int profile_b);
434 ~ProfilesMatchStatusChecker() override;
436 // StatusChangeChecker implementation.
437 bool IsExitConditionSatisfied() override;
438 std::string GetDebugMessage() const override;
440 // PersonalDataManager implementation.
441 void OnPersonalDataChanged() override;
443 // Wait for conidtion to beome true.
444 void Wait();
446 private:
447 const int profile_a_;
448 const int profile_b_;
449 bool registered_;
452 ProfilesMatchStatusChecker::ProfilesMatchStatusChecker(int profile_a,
453 int profile_b)
454 : profile_a_(profile_a), profile_b_(profile_b), registered_(false) {
457 ProfilesMatchStatusChecker::~ProfilesMatchStatusChecker() {
458 PersonalDataManager* pdm_a = GetPersonalDataManager(profile_a_);
459 PersonalDataManager* pdm_b = GetPersonalDataManager(profile_b_);
460 if (registered_) {
461 pdm_a->RemoveObserver(this);
462 pdm_b->RemoveObserver(this);
466 bool ProfilesMatchStatusChecker::IsExitConditionSatisfied() {
467 PersonalDataManager* pdm_a = GetPersonalDataManager(profile_a_);
468 PersonalDataManager* pdm_b = GetPersonalDataManager(profile_b_);
470 const std::vector<AutofillProfile*>& autofill_profiles_a =
471 pdm_a->web_profiles();
472 const std::vector<AutofillProfile*>& autofill_profiles_b =
473 pdm_b->web_profiles();
475 return ProfilesMatchImpl(
476 profile_a_, autofill_profiles_a, profile_b_, autofill_profiles_b);
479 void ProfilesMatchStatusChecker::Wait() {
480 PersonalDataManager* pdm_a = GetPersonalDataManager(profile_a_);
481 PersonalDataManager* pdm_b = GetPersonalDataManager(profile_b_);
483 pdm_a->AddObserver(this);
484 pdm_b->AddObserver(this);
486 pdm_a->Refresh();
487 pdm_b->Refresh();
489 registered_ = true;
491 StartBlockingWait();
494 std::string ProfilesMatchStatusChecker::GetDebugMessage() const {
495 return "Waiting for matching autofill profiles";
498 void ProfilesMatchStatusChecker::OnPersonalDataChanged() {
499 CheckExitCondition();
502 } // namespace
504 bool AwaitProfilesMatch(int a, int b) {
505 ProfilesMatchStatusChecker checker(a, b);
506 checker.Wait();
507 return !checker.TimedOut();
510 } // namespace autofill_helper