Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / sync / test / integration / autofill_helper.cc
bloba85af58f5b5d380c5a23d9879ce76affa0562123
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/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"
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::_;
43 namespace {
45 ACTION_P(SignalEvent, event) {
46 event->Signal();
49 class MockWebDataServiceObserver
50 : public AutofillWebDataServiceObserverOnDBThread {
51 public:
52 MOCK_METHOD1(AutofillEntriesChanged,
53 void(const AutofillChangeList& changes));
56 class MockPersonalDataManagerObserver : public PersonalDataManagerObserver {
57 public:
58 MOCK_METHOD0(OnPersonalDataChanged, void());
61 void RunOnDBThreadAndSignal(base::Closure task,
62 base::WaitableEvent* done_event) {
63 if (!task.is_null()) {
64 task.Run();
66 done_event->Signal();
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();
77 void RemoveKeyDontBlockForSync(int profile, const AutofillKey& key) {
78 WaitableEvent done_event(false, false);
80 MockWebDataServiceObserver mock_observer;
81 EXPECT_CALL(mock_observer, AutofillEntriesChanged(_))
82 .WillOnce(SignalEvent(&done_event));
84 scoped_refptr<AutofillWebDataService> wds =
85 autofill_helper::GetWebDataService(profile);
87 void(AutofillWebDataService::*add_observer_func)(
88 AutofillWebDataServiceObserverOnDBThread*) =
89 &AutofillWebDataService::AddObserver;
90 RunOnDBThreadAndBlock(Bind(add_observer_func, wds, &mock_observer));
92 wds->RemoveFormValueForElementName(key.name(), key.value());
93 done_event.Wait();
95 void(AutofillWebDataService::*remove_observer_func)(
96 AutofillWebDataServiceObserverOnDBThread*) =
97 &AutofillWebDataService::RemoveObserver;
98 RunOnDBThreadAndBlock(Bind(remove_observer_func, wds, &mock_observer));
101 void GetAllAutofillEntriesOnDBThread(AutofillWebDataService* wds,
102 std::vector<AutofillEntry>* entries) {
103 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
104 AutofillTable::FromWebDatabase(
105 wds->GetDatabase())->GetAllAutofillEntries(entries);
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;
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());
128 } // namespace
130 namespace autofill_helper {
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@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@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;
164 return profile;
167 scoped_refptr<AutofillWebDataService> GetWebDataService(int index) {
168 return WebDataServiceFactory::GetAutofillWebDataForProfile(
169 test()->GetProfile(index), Profile::EXPLICIT_ACCESS);
172 PersonalDataManager* GetPersonalDataManager(int index) {
173 return autofill::PersonalDataManagerFactory::GetForProfile(
174 test()->GetProfile(index));
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);
188 WaitableEvent done_event(false, false);
189 MockWebDataServiceObserver mock_observer;
190 EXPECT_CALL(mock_observer, AutofillEntriesChanged(_))
191 .WillOnce(SignalEvent(&done_event));
193 scoped_refptr<AutofillWebDataService> wds = GetWebDataService(profile);
195 void(AutofillWebDataService::*add_observer_func)(
196 AutofillWebDataServiceObserverOnDBThread*) =
197 &AutofillWebDataService::AddObserver;
198 RunOnDBThreadAndBlock(Bind(add_observer_func, wds, &mock_observer));
200 wds->AddFormFields(form_fields);
201 done_event.Wait();
202 BlockForPendingDBThreadTasks();
204 void(AutofillWebDataService::*remove_observer_func)(
205 AutofillWebDataServiceObserverOnDBThread*) =
206 &AutofillWebDataService::RemoveObserver;
207 RunOnDBThreadAndBlock(Bind(remove_observer_func, wds, &mock_observer));
210 void RemoveKey(int profile, const AutofillKey& key) {
211 RemoveKeyDontBlockForSync(profile, key);
212 BlockForPendingDBThreadTasks();
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());
221 BlockForPendingDBThreadTasks();
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);
232 return all_keys;
235 bool KeysMatch(int profile_a, int profile_b) {
236 return GetAllKeys(profile_a) == GetAllKeys(profile_b);
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);
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);
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);
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]);
277 autofill_helper::SetProfiles(profile, &autofill_profiles);
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);
291 autofill_helper::SetProfiles(profile, &profiles);
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();
307 int GetProfileCount(int profile) {
308 return GetAllProfiles(profile).size();
311 int GetKeyCount(int profile) {
312 return GetAllKeys(profile).size();
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;
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;
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;
339 autofill_profiles_a_map.erase(p->guid());
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;
347 return true;
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;
358 return true;
361 } // namespace autofill_helper