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 "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/multi_client_status_change_checker.h"
13 #include "chrome/browser/sync/test/integration/sync_datatype_helper.h"
14 #include "chrome/browser/sync/test/integration/sync_test.h"
15 #include "chrome/browser/webdata/web_data_service_factory.h"
16 #include "components/autofill/core/browser/autofill_profile.h"
17 #include "components/autofill/core/browser/autofill_test_utils.h"
18 #include "components/autofill/core/browser/autofill_type.h"
19 #include "components/autofill/core/browser/personal_data_manager.h"
20 #include "components/autofill/core/browser/personal_data_manager_observer.h"
21 #include "components/autofill/core/browser/webdata/autofill_entry.h"
22 #include "components/autofill/core/browser/webdata/autofill_table.h"
23 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
24 #include "components/autofill/core/common/form_field_data.h"
25 #include "components/webdata/common/web_database.h"
27 using autofill::AutofillChangeList
;
28 using autofill::AutofillEntry
;
29 using autofill::AutofillKey
;
30 using autofill::AutofillProfile
;
31 using autofill::AutofillTable
;
32 using autofill::AutofillType
;
33 using autofill::AutofillWebDataService
;
34 using autofill::AutofillWebDataServiceObserverOnDBThread
;
35 using autofill::CreditCard
;
36 using autofill::FormFieldData
;
37 using autofill::PersonalDataManager
;
38 using autofill::PersonalDataManagerObserver
;
39 using base::WaitableEvent
;
40 using content::BrowserThread
;
41 using sync_datatype_helper::test
;
46 ACTION_P(SignalEvent
, event
) {
50 class MockWebDataServiceObserver
51 : public AutofillWebDataServiceObserverOnDBThread
{
53 MOCK_METHOD1(AutofillEntriesChanged
,
54 void(const AutofillChangeList
& changes
));
57 class MockPersonalDataManagerObserver
: public PersonalDataManagerObserver
{
59 MOCK_METHOD0(OnPersonalDataChanged
, void());
62 void RunOnDBThreadAndSignal(base::Closure task
,
63 base::WaitableEvent
* done_event
) {
64 if (!task
.is_null()) {
70 void RunOnDBThreadAndBlock(base::Closure task
) {
71 WaitableEvent
done_event(false, false);
72 BrowserThread::PostTask(BrowserThread::DB
,
74 Bind(&RunOnDBThreadAndSignal
, task
, &done_event
));
78 void RemoveKeyDontBlockForSync(int profile
, const AutofillKey
& key
) {
79 WaitableEvent
done_event(false, false);
81 MockWebDataServiceObserver mock_observer
;
82 EXPECT_CALL(mock_observer
, AutofillEntriesChanged(_
))
83 .WillOnce(SignalEvent(&done_event
));
85 scoped_refptr
<AutofillWebDataService
> wds
=
86 autofill_helper::GetWebDataService(profile
);
88 void(AutofillWebDataService::*add_observer_func
)(
89 AutofillWebDataServiceObserverOnDBThread
*) =
90 &AutofillWebDataService::AddObserver
;
91 RunOnDBThreadAndBlock(Bind(add_observer_func
, wds
, &mock_observer
));
93 wds
->RemoveFormValueForElementName(key
.name(), key
.value());
96 void(AutofillWebDataService::*remove_observer_func
)(
97 AutofillWebDataServiceObserverOnDBThread
*) =
98 &AutofillWebDataService::RemoveObserver
;
99 RunOnDBThreadAndBlock(Bind(remove_observer_func
, wds
, &mock_observer
));
102 void GetAllAutofillEntriesOnDBThread(AutofillWebDataService
* wds
,
103 std::vector
<AutofillEntry
>* entries
) {
104 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB
));
105 AutofillTable::FromWebDatabase(
106 wds
->GetDatabase())->GetAllAutofillEntries(entries
);
109 std::vector
<AutofillEntry
> GetAllAutofillEntries(AutofillWebDataService
* wds
) {
110 std::vector
<AutofillEntry
> entries
;
111 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
112 RunOnDBThreadAndBlock(Bind(&GetAllAutofillEntriesOnDBThread
,
118 // UI thread returns from the update operations on the DB thread and schedules
119 // the sync. This function blocks until after this scheduled sync is complete by
120 // scheduling additional empty task on DB Thread. Call after AddKeys/RemoveKey.
121 void BlockForPendingDBThreadTasks() {
122 // The order of the notifications is undefined, so sync change sometimes is
123 // posted after the notification for observer_helper. Post new task to db
124 // thread that guaranteed to be after sync and would be blocking until
126 RunOnDBThreadAndBlock(base::Closure());
131 namespace autofill_helper
{
133 AutofillProfile
CreateAutofillProfile(ProfileType type
) {
134 AutofillProfile profile
;
137 autofill::test::SetProfileInfoWithGuid(&profile
,
138 "C837507A-6C3B-4872-AC14-5113F157D668",
139 "Marion", "Mitchell", "Morrison",
140 "johnwayne@me.xyz", "Fox",
141 "123 Zoo St.", "unit 5", "Hollywood", "CA",
142 "91601", "US", "12345678910");
145 autofill::test::SetProfileInfoWithGuid(&profile
,
146 "137DE1C3-6A30-4571-AC86-109B1ECFBE7F",
147 "Homer", "J.", "Simpson",
148 "homer@abc.com", "SNPP",
149 "1 Main St", "PO Box 1", "Springfield", "MA",
150 "94101", "US", "14155551212");
152 case PROFILE_FRASIER
:
153 autofill::test::SetProfileInfoWithGuid(&profile
,
154 "9A5E6872-6198-4688-BF75-0016E781BB0A",
155 "Frasier", "Winslow", "Crane",
156 "", "randomness", "", "Apt. 4", "Seattle", "WA",
157 "99121", "US", "0000000000");
160 autofill::test::SetProfileInfoWithGuid(&profile
,
161 "FE461507-7E13-4198-8E66-74C7DB6D8322",
162 "", "", "", "", "", "", "", "", "", "", "", "");
168 scoped_refptr
<AutofillWebDataService
> GetWebDataService(int index
) {
169 return WebDataServiceFactory::GetAutofillWebDataForProfile(
170 test()->GetProfile(index
), ServiceAccessType::EXPLICIT_ACCESS
);
173 PersonalDataManager
* GetPersonalDataManager(int index
) {
174 return autofill::PersonalDataManagerFactory::GetForProfile(
175 test()->GetProfile(index
));
178 void AddKeys(int profile
, const std::set
<AutofillKey
>& keys
) {
179 std::vector
<FormFieldData
> form_fields
;
180 for (std::set
<AutofillKey
>::const_iterator i
= keys
.begin();
184 field
.name
= i
->name();
185 field
.value
= i
->value();
186 form_fields
.push_back(field
);
189 WaitableEvent
done_event(false, false);
190 MockWebDataServiceObserver mock_observer
;
191 EXPECT_CALL(mock_observer
, AutofillEntriesChanged(_
))
192 .WillOnce(SignalEvent(&done_event
));
194 scoped_refptr
<AutofillWebDataService
> wds
= GetWebDataService(profile
);
196 void(AutofillWebDataService::*add_observer_func
)(
197 AutofillWebDataServiceObserverOnDBThread
*) =
198 &AutofillWebDataService::AddObserver
;
199 RunOnDBThreadAndBlock(Bind(add_observer_func
, wds
, &mock_observer
));
201 wds
->AddFormFields(form_fields
);
203 BlockForPendingDBThreadTasks();
205 void(AutofillWebDataService::*remove_observer_func
)(
206 AutofillWebDataServiceObserverOnDBThread
*) =
207 &AutofillWebDataService::RemoveObserver
;
208 RunOnDBThreadAndBlock(Bind(remove_observer_func
, wds
, &mock_observer
));
211 void RemoveKey(int profile
, const AutofillKey
& key
) {
212 RemoveKeyDontBlockForSync(profile
, key
);
213 BlockForPendingDBThreadTasks();
216 void RemoveKeys(int profile
) {
217 std::set
<AutofillEntry
> keys
= GetAllKeys(profile
);
218 for (std::set
<AutofillEntry
>::const_iterator it
= keys
.begin();
219 it
!= keys
.end(); ++it
) {
220 RemoveKeyDontBlockForSync(profile
, it
->key());
222 BlockForPendingDBThreadTasks();
225 std::set
<AutofillEntry
> GetAllKeys(int profile
) {
226 scoped_refptr
<AutofillWebDataService
> wds
= GetWebDataService(profile
);
227 std::vector
<AutofillEntry
> all_entries
= GetAllAutofillEntries(wds
.get());
228 std::set
<AutofillEntry
> all_keys
;
229 for (std::vector
<AutofillEntry
>::const_iterator it
= all_entries
.begin();
230 it
!= all_entries
.end(); ++it
) {
231 all_keys
.insert(*it
);
236 bool KeysMatch(int profile_a
, int profile_b
) {
237 return GetAllKeys(profile_a
) == GetAllKeys(profile_b
);
242 class KeysMatchStatusChecker
: public MultiClientStatusChangeChecker
{
244 KeysMatchStatusChecker(int profile_a
, int profile_b
);
245 ~KeysMatchStatusChecker() override
;
247 bool IsExitConditionSatisfied() override
;
248 std::string
GetDebugMessage() const override
;
251 const int profile_a_
;
252 const int profile_b_
;
255 KeysMatchStatusChecker::KeysMatchStatusChecker(int profile_a
, int profile_b
)
256 : MultiClientStatusChangeChecker(
257 sync_datatype_helper::test()->GetSyncServices()),
258 profile_a_(profile_a
),
259 profile_b_(profile_b
) {
262 KeysMatchStatusChecker::~KeysMatchStatusChecker() {
265 bool KeysMatchStatusChecker::IsExitConditionSatisfied() {
266 return KeysMatch(profile_a_
, profile_b_
);
269 std::string
KeysMatchStatusChecker::GetDebugMessage() const {
270 return "Waiting for matching autofill keys";
275 bool AwaitKeysMatch(int a
, int b
) {
276 KeysMatchStatusChecker
checker(a
, b
);
278 return !checker
.TimedOut();
281 void SetProfiles(int profile
, std::vector
<AutofillProfile
>* autofill_profiles
) {
282 MockPersonalDataManagerObserver observer
;
283 EXPECT_CALL(observer
, OnPersonalDataChanged()).
284 WillOnce(QuitUIMessageLoop());
285 PersonalDataManager
* pdm
= GetPersonalDataManager(profile
);
286 pdm
->AddObserver(&observer
);
287 pdm
->SetProfiles(autofill_profiles
);
288 base::MessageLoop::current()->Run();
289 pdm
->RemoveObserver(&observer
);
292 void SetCreditCards(int profile
, std::vector
<CreditCard
>* credit_cards
) {
293 MockPersonalDataManagerObserver observer
;
294 EXPECT_CALL(observer
, OnPersonalDataChanged()).
295 WillOnce(QuitUIMessageLoop());
296 PersonalDataManager
* pdm
= GetPersonalDataManager(profile
);
297 pdm
->AddObserver(&observer
);
298 pdm
->SetCreditCards(credit_cards
);
299 base::MessageLoop::current()->Run();
300 pdm
->RemoveObserver(&observer
);
303 void AddProfile(int profile
, const AutofillProfile
& autofill_profile
) {
304 const std::vector
<AutofillProfile
*>& all_profiles
= GetAllProfiles(profile
);
305 std::vector
<AutofillProfile
> autofill_profiles
;
306 for (size_t i
= 0; i
< all_profiles
.size(); ++i
)
307 autofill_profiles
.push_back(*all_profiles
[i
]);
308 autofill_profiles
.push_back(autofill_profile
);
309 autofill_helper::SetProfiles(profile
, &autofill_profiles
);
312 void RemoveProfile(int profile
, const std::string
& guid
) {
313 const std::vector
<AutofillProfile
*>& all_profiles
= GetAllProfiles(profile
);
314 std::vector
<AutofillProfile
> autofill_profiles
;
315 for (size_t i
= 0; i
< all_profiles
.size(); ++i
) {
316 if (all_profiles
[i
]->guid() != guid
)
317 autofill_profiles
.push_back(*all_profiles
[i
]);
319 autofill_helper::SetProfiles(profile
, &autofill_profiles
);
322 void UpdateProfile(int profile
,
323 const std::string
& guid
,
324 const AutofillType
& type
,
325 const base::string16
& value
) {
326 const std::vector
<AutofillProfile
*>& all_profiles
= GetAllProfiles(profile
);
327 std::vector
<AutofillProfile
> profiles
;
328 for (size_t i
= 0; i
< all_profiles
.size(); ++i
) {
329 profiles
.push_back(*all_profiles
[i
]);
330 if (all_profiles
[i
]->guid() == guid
)
331 profiles
.back().SetRawInfo(type
.GetStorableType(), value
);
333 autofill_helper::SetProfiles(profile
, &profiles
);
336 const std::vector
<AutofillProfile
*>& GetAllProfiles(
338 MockPersonalDataManagerObserver observer
;
339 EXPECT_CALL(observer
, OnPersonalDataChanged()).
340 WillOnce(QuitUIMessageLoop());
341 PersonalDataManager
* pdm
= GetPersonalDataManager(profile
);
342 pdm
->AddObserver(&observer
);
344 base::MessageLoop::current()->Run();
345 pdm
->RemoveObserver(&observer
);
346 return pdm
->web_profiles();
349 int GetProfileCount(int profile
) {
350 return GetAllProfiles(profile
).size();
353 int GetKeyCount(int profile
) {
354 return GetAllKeys(profile
).size();
359 bool ProfilesMatchImpl(
361 const std::vector
<AutofillProfile
*>& autofill_profiles_a
,
363 const std::vector
<AutofillProfile
*>& autofill_profiles_b
) {
364 std::map
<std::string
, AutofillProfile
> autofill_profiles_a_map
;
365 for (size_t i
= 0; i
< autofill_profiles_a
.size(); ++i
) {
366 const AutofillProfile
* p
= autofill_profiles_a
[i
];
367 autofill_profiles_a_map
[p
->guid()] = *p
;
370 for (size_t i
= 0; i
< autofill_profiles_b
.size(); ++i
) {
371 const AutofillProfile
* p
= autofill_profiles_b
[i
];
372 if (!autofill_profiles_a_map
.count(p
->guid())) {
373 DVLOG(1) << "GUID " << p
->guid() << " not found in profile " << profile_b
377 AutofillProfile
* expected_profile
= &autofill_profiles_a_map
[p
->guid()];
378 expected_profile
->set_guid(p
->guid());
379 if (*expected_profile
!= *p
) {
380 DVLOG(1) << "Mismatch in profile with GUID " << p
->guid() << ".";
383 autofill_profiles_a_map
.erase(p
->guid());
386 if (autofill_profiles_a_map
.size()) {
387 DVLOG(1) << "Entries present in Profile " << profile_a
<< " but not in "
396 bool ProfilesMatch(int profile_a
, int profile_b
) {
397 const std::vector
<AutofillProfile
*>& autofill_profiles_a
=
398 GetAllProfiles(profile_a
);
399 const std::vector
<AutofillProfile
*>& autofill_profiles_b
=
400 GetAllProfiles(profile_b
);
401 return ProfilesMatchImpl(
402 profile_a
, autofill_profiles_a
, profile_b
, autofill_profiles_b
);
405 bool AllProfilesMatch() {
406 for (int i
= 1; i
< test()->num_clients(); ++i
) {
407 if (!ProfilesMatch(0, i
)) {
408 DVLOG(1) << "Profile " << i
<< "does not contain the same autofill "
409 "profiles as profile 0.";
418 class ProfilesMatchStatusChecker
: public StatusChangeChecker
,
419 public PersonalDataManagerObserver
{
421 ProfilesMatchStatusChecker(int profile_a
, int profile_b
);
422 ~ProfilesMatchStatusChecker() override
;
424 // StatusChangeChecker implementation.
425 bool IsExitConditionSatisfied() override
;
426 std::string
GetDebugMessage() const override
;
428 // PersonalDataManager implementation.
429 void OnPersonalDataChanged() override
;
431 // Wait for conidtion to beome true.
435 const int profile_a_
;
436 const int profile_b_
;
440 ProfilesMatchStatusChecker::ProfilesMatchStatusChecker(int profile_a
,
442 : profile_a_(profile_a
), profile_b_(profile_b
), registered_(false) {
445 ProfilesMatchStatusChecker::~ProfilesMatchStatusChecker() {
446 PersonalDataManager
* pdm_a
= GetPersonalDataManager(profile_a_
);
447 PersonalDataManager
* pdm_b
= GetPersonalDataManager(profile_b_
);
449 pdm_a
->RemoveObserver(this);
450 pdm_b
->RemoveObserver(this);
454 bool ProfilesMatchStatusChecker::IsExitConditionSatisfied() {
455 PersonalDataManager
* pdm_a
= GetPersonalDataManager(profile_a_
);
456 PersonalDataManager
* pdm_b
= GetPersonalDataManager(profile_b_
);
458 const std::vector
<AutofillProfile
*>& autofill_profiles_a
=
459 pdm_a
->web_profiles();
460 const std::vector
<AutofillProfile
*>& autofill_profiles_b
=
461 pdm_b
->web_profiles();
463 return ProfilesMatchImpl(
464 profile_a_
, autofill_profiles_a
, profile_b_
, autofill_profiles_b
);
467 void ProfilesMatchStatusChecker::Wait() {
468 PersonalDataManager
* pdm_a
= GetPersonalDataManager(profile_a_
);
469 PersonalDataManager
* pdm_b
= GetPersonalDataManager(profile_b_
);
471 pdm_a
->AddObserver(this);
472 pdm_b
->AddObserver(this);
482 std::string
ProfilesMatchStatusChecker::GetDebugMessage() const {
483 return "Waiting for matching autofill profiles";
486 void ProfilesMatchStatusChecker::OnPersonalDataChanged() {
487 CheckExitCondition();
492 bool AwaitProfilesMatch(int a
, int b
) {
493 ProfilesMatchStatusChecker
checker(a
, b
);
495 return !checker
.TimedOut();
498 } // namespace autofill_helper