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"
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
;
47 ACTION_P(SignalEvent
, event
) {
51 class MockWebDataServiceObserver
52 : public AutofillWebDataServiceObserverOnDBThread
{
54 MOCK_METHOD1(AutofillEntriesChanged
,
55 void(const AutofillChangeList
& changes
));
58 class MockPersonalDataManagerObserver
: public PersonalDataManagerObserver
{
60 MOCK_METHOD0(OnPersonalDataChanged
, void());
63 void RunOnDBThreadAndSignal(base::Closure task
,
64 base::WaitableEvent
* done_event
) {
65 if (!task
.is_null()) {
71 void RunOnDBThreadAndBlock(base::Closure task
) {
72 WaitableEvent
done_event(false, false);
73 BrowserThread::PostTask(BrowserThread::DB
,
75 Bind(&RunOnDBThreadAndSignal
, task
, &done_event
));
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());
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
,
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
127 RunOnDBThreadAndBlock(base::Closure());
132 namespace autofill_helper
{
134 AutofillProfile
CreateAutofillProfile(ProfileType type
) {
135 AutofillProfile profile
;
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");
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");
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");
161 autofill::test::SetProfileInfoWithGuid(&profile
,
162 "FE461507-7E13-4198-8E66-74C7DB6D8322",
163 "", "", "", "", "", "", "", "", "", "", "", "");
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");
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();
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
);
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
);
248 bool KeysMatch(int profile_a
, int profile_b
) {
249 return GetAllKeys(profile_a
) == GetAllKeys(profile_b
);
254 class KeysMatchStatusChecker
: public MultiClientStatusChangeChecker
{
256 KeysMatchStatusChecker(int profile_a
, int profile_b
);
257 ~KeysMatchStatusChecker() override
;
259 bool IsExitConditionSatisfied() override
;
260 std::string
GetDebugMessage() const override
;
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";
287 bool AwaitKeysMatch(int a
, int b
) {
288 KeysMatchStatusChecker
checker(a
, b
);
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(
350 MockPersonalDataManagerObserver observer
;
351 EXPECT_CALL(observer
, OnPersonalDataChanged()).
352 WillOnce(QuitUIMessageLoop());
353 PersonalDataManager
* pdm
= GetPersonalDataManager(profile
);
354 pdm
->AddObserver(&observer
);
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();
371 bool ProfilesMatchImpl(
373 const std::vector
<AutofillProfile
*>& autofill_profiles_a
,
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
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() << ".";
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 "
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.";
430 class ProfilesMatchStatusChecker
: public StatusChangeChecker
,
431 public PersonalDataManagerObserver
{
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.
447 const int profile_a_
;
448 const int profile_b_
;
452 ProfilesMatchStatusChecker::ProfilesMatchStatusChecker(int profile_a
,
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_
);
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);
494 std::string
ProfilesMatchStatusChecker::GetDebugMessage() const {
495 return "Waiting for matching autofill profiles";
498 void ProfilesMatchStatusChecker::OnPersonalDataChanged() {
499 CheckExitCondition();
504 bool AwaitProfilesMatch(int a
, int b
) {
505 ProfilesMatchStatusChecker
checker(a
, b
);
507 return !checker
.TimedOut();
510 } // namespace autofill_helper