blob: e4a7f61031bfa674b4f71609918f72a38d4af8ad [file] [log] [blame]
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001// 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
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007#include "chrome/browser/autofill/personal_data_manager_factory.h"
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01008#include "chrome/browser/chrome_notification_types.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +00009#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"
Ben Murdocheb525c52013-07-10 11:40:50 +010014#include "components/autofill/core/browser/autofill_common_test.h"
15#include "components/autofill/core/browser/autofill_profile.h"
16#include "components/autofill/core/browser/autofill_type.h"
17#include "components/autofill/core/browser/personal_data_manager.h"
18#include "components/autofill/core/browser/personal_data_manager_observer.h"
19#include "components/autofill/core/browser/webdata/autofill_entry.h"
20#include "components/autofill/core/browser/webdata/autofill_table.h"
21#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +010022#include "components/autofill/core/common/form_field_data.h"
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010023#include "components/webdata/common/web_database.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000024
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010025using autofill::AutofillChangeList;
26using autofill::AutofillEntry;
27using autofill::AutofillKey;
28using autofill::AutofillProfile;
29using autofill::AutofillTable;
30using autofill::AutofillType;
31using autofill::AutofillWebDataService;
32using autofill::AutofillWebDataServiceObserverOnDBThread;
33using autofill::CreditCard;
34using autofill::FormFieldData;
35using autofill::PersonalDataManager;
36using autofill::PersonalDataManagerObserver;
Torne (Richard Coles)58218062012-11-14 11:43:16 +000037using base::WaitableEvent;
38using content::BrowserThread;
39using sync_datatype_helper::test;
40using testing::_;
41
42namespace {
43
44ACTION_P(SignalEvent, event) {
45 event->Signal();
46}
47
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010048class MockWebDataServiceObserver
49 : public AutofillWebDataServiceObserverOnDBThread {
50 public:
51 MOCK_METHOD1(AutofillEntriesChanged,
52 void(const AutofillChangeList& changes));
Torne (Richard Coles)58218062012-11-14 11:43:16 +000053};
54
55class MockPersonalDataManagerObserver : public PersonalDataManagerObserver {
56 public:
57 MOCK_METHOD0(OnPersonalDataChanged, void());
58};
59
Torne (Richard Coles)58218062012-11-14 11:43:16 +000060void RunOnDBThreadAndSignal(base::Closure task,
61 base::WaitableEvent* done_event) {
62 if (!task.is_null()) {
63 task.Run();
64 }
65 done_event->Signal();
66}
67
68void RunOnDBThreadAndBlock(base::Closure task) {
69 WaitableEvent done_event(false, false);
70 BrowserThread::PostTask(BrowserThread::DB,
71 FROM_HERE,
72 Bind(&RunOnDBThreadAndSignal, task, &done_event));
73 done_event.Wait();
74}
75
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010076void RemoveKeyDontBlockForSync(int profile, const AutofillKey& key) {
77 WaitableEvent done_event(false, false);
78
79 MockWebDataServiceObserver mock_observer;
80 EXPECT_CALL(mock_observer, AutofillEntriesChanged(_))
81 .WillOnce(SignalEvent(&done_event));
82
83 scoped_refptr<AutofillWebDataService> wds =
84 autofill_helper::GetWebDataService(profile);
85
86 void(AutofillWebDataService::*add_observer_func)(
87 AutofillWebDataServiceObserverOnDBThread*) =
88 &AutofillWebDataService::AddObserver;
89 RunOnDBThreadAndBlock(Bind(add_observer_func, wds, &mock_observer));
90
91 wds->RemoveFormValueForElementName(key.name(), key.value());
92 done_event.Wait();
93
94 void(AutofillWebDataService::*remove_observer_func)(
95 AutofillWebDataServiceObserverOnDBThread*) =
96 &AutofillWebDataService::RemoveObserver;
97 RunOnDBThreadAndBlock(Bind(remove_observer_func, wds, &mock_observer));
98}
99
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000100void GetAllAutofillEntriesOnDBThread(AutofillWebDataService* wds,
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000101 std::vector<AutofillEntry>* entries) {
102 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000103 AutofillTable::FromWebDatabase(
104 wds->GetDatabase())->GetAllAutofillEntries(entries);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000105}
106
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000107std::vector<AutofillEntry> GetAllAutofillEntries(AutofillWebDataService* wds) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000108 std::vector<AutofillEntry> entries;
109 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
110 RunOnDBThreadAndBlock(Bind(&GetAllAutofillEntriesOnDBThread,
111 Unretained(wds),
112 &entries));
113 return entries;
114}
115
116// UI thread returns from the update operations on the DB thread and schedules
117// the sync. This function blocks until after this scheduled sync is complete by
118// scheduling additional empty task on DB Thread. Call after AddKeys/RemoveKey.
119void BlockForPendingDBThreadTasks() {
120 // The order of the notifications is undefined, so sync change sometimes is
121 // posted after the notification for observer_helper. Post new task to db
122 // thread that guaranteed to be after sync and would be blocking until
123 // completion.
124 RunOnDBThreadAndBlock(base::Closure());
125}
126
127} // namespace
128
129namespace autofill_helper {
130
131AutofillProfile CreateAutofillProfile(ProfileType type) {
132 AutofillProfile profile;
133 switch (type) {
134 case PROFILE_MARION:
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100135 autofill::test::SetProfileInfoWithGuid(&profile,
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000136 "C837507A-6C3B-4872-AC14-5113F157D668",
137 "Marion", "Mitchell", "Morrison",
138 "johnwayne@me.xyz", "Fox",
139 "123 Zoo St.", "unit 5", "Hollywood", "CA",
140 "91601", "US", "12345678910");
141 break;
142 case PROFILE_HOMER:
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100143 autofill::test::SetProfileInfoWithGuid(&profile,
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000144 "137DE1C3-6A30-4571-AC86-109B1ECFBE7F",
145 "Homer", "J.", "Simpson",
146 "homer@abc.com", "SNPP",
147 "1 Main St", "PO Box 1", "Springfield", "MA",
148 "94101", "US", "14155551212");
149 break;
150 case PROFILE_FRASIER:
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100151 autofill::test::SetProfileInfoWithGuid(&profile,
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000152 "9A5E6872-6198-4688-BF75-0016E781BB0A",
153 "Frasier", "Winslow", "Crane",
154 "", "randomness", "", "Apt. 4", "Seattle", "WA",
155 "99121", "US", "0000000000");
156 break;
157 case PROFILE_NULL:
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100158 autofill::test::SetProfileInfoWithGuid(&profile,
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000159 "FE461507-7E13-4198-8E66-74C7DB6D8322",
160 "", "", "", "", "", "", "", "", "", "", "", "");
161 break;
162 }
163 return profile;
164}
165
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000166scoped_refptr<AutofillWebDataService> GetWebDataService(int index) {
167 return AutofillWebDataService::FromBrowserContext(test()->GetProfile(index));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000168}
169
170PersonalDataManager* GetPersonalDataManager(int index) {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100171 return autofill::PersonalDataManagerFactory::GetForProfile(
172 test()->GetProfile(index));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000173}
174
175void AddKeys(int profile, const std::set<AutofillKey>& keys) {
176 std::vector<FormFieldData> form_fields;
177 for (std::set<AutofillKey>::const_iterator i = keys.begin();
178 i != keys.end();
179 ++i) {
180 FormFieldData field;
181 field.name = i->name();
182 field.value = i->value();
183 form_fields.push_back(field);
184 }
185
186 WaitableEvent done_event(false, false);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100187 MockWebDataServiceObserver mock_observer;
188 EXPECT_CALL(mock_observer, AutofillEntriesChanged(_))
189 .WillOnce(SignalEvent(&done_event));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000190
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000191 scoped_refptr<AutofillWebDataService> wds = GetWebDataService(profile);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100192
193 void(AutofillWebDataService::*add_observer_func)(
194 AutofillWebDataServiceObserverOnDBThread*) =
195 &AutofillWebDataService::AddObserver;
196 RunOnDBThreadAndBlock(Bind(add_observer_func, wds, &mock_observer));
197
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000198 wds->AddFormFields(form_fields);
199 done_event.Wait();
200 BlockForPendingDBThreadTasks();
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100201
202 void(AutofillWebDataService::*remove_observer_func)(
203 AutofillWebDataServiceObserverOnDBThread*) =
204 &AutofillWebDataService::RemoveObserver;
205 RunOnDBThreadAndBlock(Bind(remove_observer_func, wds, &mock_observer));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000206}
207
208void RemoveKey(int profile, const AutofillKey& key) {
209 RemoveKeyDontBlockForSync(profile, key);
210 BlockForPendingDBThreadTasks();
211}
212
213void RemoveKeys(int profile) {
214 std::set<AutofillEntry> keys = GetAllKeys(profile);
215 for (std::set<AutofillEntry>::const_iterator it = keys.begin();
216 it != keys.end(); ++it) {
217 RemoveKeyDontBlockForSync(profile, it->key());
218 }
219 BlockForPendingDBThreadTasks();
220}
221
222std::set<AutofillEntry> GetAllKeys(int profile) {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000223 scoped_refptr<AutofillWebDataService> wds = GetWebDataService(profile);
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100224 std::vector<AutofillEntry> all_entries = GetAllAutofillEntries(wds.get());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000225 std::set<AutofillEntry> all_keys;
226 for (std::vector<AutofillEntry>::const_iterator it = all_entries.begin();
227 it != all_entries.end(); ++it) {
228 all_keys.insert(*it);
229 }
230 return all_keys;
231}
232
233bool KeysMatch(int profile_a, int profile_b) {
234 return GetAllKeys(profile_a) == GetAllKeys(profile_b);
235}
236
237void SetProfiles(int profile, std::vector<AutofillProfile>* autofill_profiles) {
238 MockPersonalDataManagerObserver observer;
239 EXPECT_CALL(observer, OnPersonalDataChanged()).
240 WillOnce(QuitUIMessageLoop());
241 PersonalDataManager* pdm = GetPersonalDataManager(profile);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000242 pdm->AddObserver(&observer);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000243 pdm->SetProfiles(autofill_profiles);
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100244 base::MessageLoop::current()->Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000245 pdm->RemoveObserver(&observer);
246}
247
248void SetCreditCards(int profile, std::vector<CreditCard>* credit_cards) {
249 MockPersonalDataManagerObserver observer;
250 EXPECT_CALL(observer, OnPersonalDataChanged()).
251 WillOnce(QuitUIMessageLoop());
252 PersonalDataManager* pdm = GetPersonalDataManager(profile);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000253 pdm->AddObserver(&observer);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000254 pdm->SetCreditCards(credit_cards);
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100255 base::MessageLoop::current()->Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000256 pdm->RemoveObserver(&observer);
257}
258
259void AddProfile(int profile, const AutofillProfile& autofill_profile) {
260 const std::vector<AutofillProfile*>& all_profiles = GetAllProfiles(profile);
261 std::vector<AutofillProfile> autofill_profiles;
262 for (size_t i = 0; i < all_profiles.size(); ++i)
263 autofill_profiles.push_back(*all_profiles[i]);
264 autofill_profiles.push_back(autofill_profile);
265 autofill_helper::SetProfiles(profile, &autofill_profiles);
266}
267
268void RemoveProfile(int profile, const std::string& guid) {
269 const std::vector<AutofillProfile*>& all_profiles = GetAllProfiles(profile);
270 std::vector<AutofillProfile> autofill_profiles;
271 for (size_t i = 0; i < all_profiles.size(); ++i) {
272 if (all_profiles[i]->guid() != guid)
273 autofill_profiles.push_back(*all_profiles[i]);
274 }
275 autofill_helper::SetProfiles(profile, &autofill_profiles);
276}
277
278void UpdateProfile(int profile,
279 const std::string& guid,
280 const AutofillType& type,
281 const string16& value) {
282 const std::vector<AutofillProfile*>& all_profiles = GetAllProfiles(profile);
283 std::vector<AutofillProfile> profiles;
284 for (size_t i = 0; i < all_profiles.size(); ++i) {
285 profiles.push_back(*all_profiles[i]);
286 if (all_profiles[i]->guid() == guid)
Ben Murdochbb1529c2013-08-08 10:24:53 +0100287 profiles.back().SetRawInfo(type.GetStorableType(), value);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000288 }
289 autofill_helper::SetProfiles(profile, &profiles);
290}
291
292const std::vector<AutofillProfile*>& GetAllProfiles(
293 int profile) {
294 MockPersonalDataManagerObserver observer;
295 EXPECT_CALL(observer, OnPersonalDataChanged()).
296 WillOnce(QuitUIMessageLoop());
297 PersonalDataManager* pdm = GetPersonalDataManager(profile);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000298 pdm->AddObserver(&observer);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000299 pdm->Refresh();
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100300 base::MessageLoop::current()->Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000301 pdm->RemoveObserver(&observer);
302 return pdm->web_profiles();
303}
304
305int GetProfileCount(int profile) {
306 return GetAllProfiles(profile).size();
307}
308
309int GetKeyCount(int profile) {
310 return GetAllKeys(profile).size();
311}
312
313bool ProfilesMatch(int profile_a, int profile_b) {
314 const std::vector<AutofillProfile*>& autofill_profiles_a =
315 GetAllProfiles(profile_a);
316 std::map<std::string, AutofillProfile> autofill_profiles_a_map;
317 for (size_t i = 0; i < autofill_profiles_a.size(); ++i) {
318 const AutofillProfile* p = autofill_profiles_a[i];
319 autofill_profiles_a_map[p->guid()] = *p;
320 }
321
322 const std::vector<AutofillProfile*>& autofill_profiles_b =
323 GetAllProfiles(profile_b);
324 for (size_t i = 0; i < autofill_profiles_b.size(); ++i) {
325 const AutofillProfile* p = autofill_profiles_b[i];
326 if (!autofill_profiles_a_map.count(p->guid())) {
327 LOG(ERROR) << "GUID " << p->guid() << " not found in profile "
328 << profile_b << ".";
329 return false;
330 }
331 AutofillProfile* expected_profile = &autofill_profiles_a_map[p->guid()];
332 expected_profile->set_guid(p->guid());
333 if (*expected_profile != *p) {
334 LOG(ERROR) << "Mismatch in profile with GUID " << p->guid() << ".";
335 return false;
336 }
337 autofill_profiles_a_map.erase(p->guid());
338 }
339
340 if (autofill_profiles_a_map.size()) {
341 LOG(ERROR) << "Entries present in Profile " << profile_a
342 << " but not in " << profile_b << ".";
343 return false;
344 }
345 return true;
346}
347
348bool AllProfilesMatch() {
349 for (int i = 1; i < test()->num_clients(); ++i) {
350 if (!ProfilesMatch(0, i)) {
351 LOG(ERROR) << "Profile " << i << "does not contain the same autofill "
352 "profiles as profile 0.";
353 return false;
354 }
355 }
356 return true;
357}
358
359} // namespace autofill_helper