1 // Copyright 2013 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.
8 #include "base/basictypes.h"
10 #include "base/files/scoped_temp_dir.h"
11 #include "base/memory/ref_counted.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/memory/scoped_vector.h"
14 #include "base/message_loop/message_loop.h"
15 #include "base/stl_util.h"
16 #include "base/strings/string16.h"
17 #include "base/strings/string_util.h"
18 #include "base/strings/utf_string_conversions.h"
19 #include "base/synchronization/waitable_event.h"
20 #include "base/threading/thread.h"
21 #include "base/time/time.h"
22 #include "components/autofill/core/browser/autofill_country.h"
23 #include "components/autofill/core/browser/autofill_profile.h"
24 #include "components/autofill/core/browser/credit_card.h"
25 #include "components/autofill/core/browser/webdata/autofill_change.h"
26 #include "components/autofill/core/browser/webdata/autofill_entry.h"
27 #include "components/autofill/core/browser/webdata/autofill_table.h"
28 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
29 #include "components/autofill/core/browser/webdata/autofill_webdata_service_observer.h"
30 #include "components/autofill/core/common/form_field_data.h"
31 #include "components/webdata/common/web_data_results.h"
32 #include "components/webdata/common/web_data_service_base.h"
33 #include "components/webdata/common/web_data_service_consumer.h"
34 #include "components/webdata/common/web_database_service.h"
35 #include "testing/gmock/include/gmock/gmock.h"
36 #include "testing/gtest/include/gtest/gtest.h"
38 using base::ASCIIToUTF16;
40 using base::TimeDelta;
41 using base::WaitableEvent;
43 using testing::DoDefault;
44 using testing::ElementsAreArray;
45 using testing::Pointee;
46 using testing::Property;
51 class AutofillWebDataServiceConsumer: public WebDataServiceConsumer {
53 AutofillWebDataServiceConsumer() : handle_(0) {}
54 virtual ~AutofillWebDataServiceConsumer() {}
56 virtual void OnWebDataServiceRequestDone(WebDataServiceBase::Handle handle,
57 const WDTypedResult* result) {
59 const WDResult<T>* wrapped_result =
60 static_cast<const WDResult<T>*>(result);
61 result_ = wrapped_result->GetValue();
63 base::MessageLoop::current()->Quit();
66 WebDataServiceBase::Handle handle() { return handle_; }
67 T& result() { return result_; }
70 WebDataServiceBase::Handle handle_;
72 DISALLOW_COPY_AND_ASSIGN(AutofillWebDataServiceConsumer);
79 static const int kWebDataServiceTimeoutSeconds = 8;
81 ACTION_P(SignalEvent, event) {
85 class MockAutofillWebDataServiceObserver
86 : public AutofillWebDataServiceObserverOnDBThread {
88 MOCK_METHOD1(AutofillEntriesChanged,
89 void(const AutofillChangeList& changes));
90 MOCK_METHOD1(AutofillProfileChanged,
91 void(const AutofillProfileChange& change));
94 class WebDataServiceTest : public testing::Test {
96 WebDataServiceTest() : db_thread_("DBThread") {}
99 void SetUp() override {
102 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
103 base::FilePath path = temp_dir_.path().AppendASCII("TestWebDB");
105 wdbs_ = new WebDatabaseService(path,
106 base::MessageLoopProxy::current(),
107 db_thread_.message_loop_proxy());
108 wdbs_->AddTable(scoped_ptr<WebDatabaseTable>(new AutofillTable("en-US")));
109 wdbs_->LoadDatabase();
112 new AutofillWebDataService(wdbs_,
113 base::MessageLoopProxy::current(),
114 db_thread_.message_loop_proxy(),
115 WebDataServiceBase::ProfileErrorCallback());
119 void TearDown() override {
120 wds_->ShutdownOnUIThread();
121 wdbs_->ShutdownDatabase();
124 WaitForDatabaseThread();
126 base::MessageLoop::current()->PostTask(FROM_HERE,
127 base::MessageLoop::QuitClosure());
128 base::MessageLoop::current()->Run();
132 void WaitForDatabaseThread() {
133 base::WaitableEvent done(false, false);
134 db_thread_.message_loop()->PostTask(
136 base::Bind(&base::WaitableEvent::Signal, base::Unretained(&done)));
140 base::MessageLoopForUI message_loop_;
141 base::Thread db_thread_;
142 base::FilePath profile_dir_;
143 scoped_refptr<AutofillWebDataService> wds_;
144 scoped_refptr<WebDatabaseService> wdbs_;
145 base::ScopedTempDir temp_dir_;
148 class WebDataServiceAutofillTest : public WebDataServiceTest {
150 WebDataServiceAutofillTest()
151 : WebDataServiceTest(),
154 test_timeout_(TimeDelta::FromSeconds(kWebDataServiceTimeoutSeconds)),
155 done_event_(false, false) {}
158 virtual void SetUp() {
159 WebDataServiceTest::SetUp();
160 name1_ = ASCIIToUTF16("name1");
161 name2_ = ASCIIToUTF16("name2");
162 value1_ = ASCIIToUTF16("value1");
163 value2_ = ASCIIToUTF16("value2");
165 void(AutofillWebDataService::*add_observer_func)(
166 AutofillWebDataServiceObserverOnDBThread*) =
167 &AutofillWebDataService::AddObserver;
168 db_thread_.message_loop()->PostTask(
169 FROM_HERE, base::Bind(add_observer_func, wds_, &observer_));
170 WaitForDatabaseThread();
173 virtual void TearDown() {
174 void(AutofillWebDataService::*remove_observer_func)(
175 AutofillWebDataServiceObserverOnDBThread*) =
176 &AutofillWebDataService::RemoveObserver;
177 db_thread_.message_loop()->PostTask(
178 FROM_HERE, base::Bind(remove_observer_func, wds_, &observer_));
179 WaitForDatabaseThread();
181 WebDataServiceTest::TearDown();
184 void AppendFormField(const base::string16& name,
185 const base::string16& value,
186 std::vector<FormFieldData>* form_fields) {
190 form_fields->push_back(field);
193 base::string16 name1_;
194 base::string16 name2_;
195 base::string16 value1_;
196 base::string16 value2_;
197 int unique_id1_, unique_id2_;
198 const TimeDelta test_timeout_;
199 testing::NiceMock<MockAutofillWebDataServiceObserver> observer_;
200 WaitableEvent done_event_;
203 TEST_F(WebDataServiceAutofillTest, FormFillAdd) {
204 const AutofillChange expected_changes[] = {
205 AutofillChange(AutofillChange::ADD, AutofillKey(name1_, value1_)),
206 AutofillChange(AutofillChange::ADD, AutofillKey(name2_, value2_))
209 // This will verify that the correct notification is triggered,
210 // passing the correct list of autofill keys in the details.
211 EXPECT_CALL(observer_,
212 AutofillEntriesChanged(ElementsAreArray(expected_changes)))
213 .WillOnce(SignalEvent(&done_event_));
215 std::vector<FormFieldData> form_fields;
216 AppendFormField(name1_, value1_, &form_fields);
217 AppendFormField(name2_, value2_, &form_fields);
218 wds_->AddFormFields(form_fields);
220 // The event will be signaled when the mock observer is notified.
221 done_event_.TimedWait(test_timeout_);
223 AutofillWebDataServiceConsumer<std::vector<base::string16> > consumer;
224 WebDataServiceBase::Handle handle;
225 static const int limit = 10;
226 handle = wds_->GetFormValuesForElementName(
227 name1_, base::string16(), limit, &consumer);
229 // The message loop will exit when the consumer is called.
230 base::MessageLoop::current()->Run();
232 EXPECT_EQ(handle, consumer.handle());
233 ASSERT_EQ(1U, consumer.result().size());
234 EXPECT_EQ(value1_, consumer.result()[0]);
237 TEST_F(WebDataServiceAutofillTest, FormFillRemoveOne) {
238 // First add some values to autofill.
239 EXPECT_CALL(observer_, AutofillEntriesChanged(_))
240 .WillOnce(SignalEvent(&done_event_));
241 std::vector<FormFieldData> form_fields;
242 AppendFormField(name1_, value1_, &form_fields);
243 wds_->AddFormFields(form_fields);
245 // The event will be signaled when the mock observer is notified.
246 done_event_.TimedWait(test_timeout_);
248 // This will verify that the correct notification is triggered,
249 // passing the correct list of autofill keys in the details.
250 const AutofillChange expected_changes[] = {
251 AutofillChange(AutofillChange::REMOVE, AutofillKey(name1_, value1_))
253 EXPECT_CALL(observer_,
254 AutofillEntriesChanged(ElementsAreArray(expected_changes)))
255 .WillOnce(SignalEvent(&done_event_));
256 wds_->RemoveFormValueForElementName(name1_, value1_);
258 // The event will be signaled when the mock observer is notified.
259 done_event_.TimedWait(test_timeout_);
262 TEST_F(WebDataServiceAutofillTest, FormFillRemoveMany) {
263 TimeDelta one_day(TimeDelta::FromDays(1));
264 Time t = Time::Now();
266 EXPECT_CALL(observer_, AutofillEntriesChanged(_))
267 .WillOnce(SignalEvent(&done_event_));
269 std::vector<FormFieldData> form_fields;
270 AppendFormField(name1_, value1_, &form_fields);
271 AppendFormField(name2_, value2_, &form_fields);
272 wds_->AddFormFields(form_fields);
274 // The event will be signaled when the mock observer is notified.
275 done_event_.TimedWait(test_timeout_);
277 // This will verify that the correct notification is triggered,
278 // passing the correct list of autofill keys in the details.
279 const AutofillChange expected_changes[] = {
280 AutofillChange(AutofillChange::REMOVE, AutofillKey(name1_, value1_)),
281 AutofillChange(AutofillChange::REMOVE, AutofillKey(name2_, value2_))
283 EXPECT_CALL(observer_,
284 AutofillEntriesChanged(ElementsAreArray(expected_changes)))
285 .WillOnce(SignalEvent(&done_event_));
286 wds_->RemoveFormElementsAddedBetween(t, t + one_day);
288 // The event will be signaled when the mock observer is notified.
289 done_event_.TimedWait(test_timeout_);
292 TEST_F(WebDataServiceAutofillTest, ProfileAdd) {
293 AutofillProfile profile;
295 // Check that GUID-based notification was sent.
296 const AutofillProfileChange expected_change(
297 AutofillProfileChange::ADD, profile.guid(), &profile);
298 EXPECT_CALL(observer_, AutofillProfileChanged(expected_change))
299 .WillOnce(SignalEvent(&done_event_));
301 wds_->AddAutofillProfile(profile);
302 done_event_.TimedWait(test_timeout_);
304 // Check that it was added.
305 AutofillWebDataServiceConsumer<std::vector<AutofillProfile*> > consumer;
306 WebDataServiceBase::Handle handle = wds_->GetAutofillProfiles(&consumer);
307 base::MessageLoop::current()->Run();
308 EXPECT_EQ(handle, consumer.handle());
309 ASSERT_EQ(1U, consumer.result().size());
310 EXPECT_EQ(profile, *consumer.result()[0]);
311 STLDeleteElements(&consumer.result());
314 TEST_F(WebDataServiceAutofillTest, ProfileRemove) {
315 AutofillProfile profile;
318 EXPECT_CALL(observer_, AutofillProfileChanged(_))
319 .WillOnce(SignalEvent(&done_event_));
320 wds_->AddAutofillProfile(profile);
321 done_event_.TimedWait(test_timeout_);
323 // Check that it was added.
324 AutofillWebDataServiceConsumer<std::vector<AutofillProfile*> > consumer;
325 WebDataServiceBase::Handle handle = wds_->GetAutofillProfiles(&consumer);
326 base::MessageLoop::current()->Run();
327 EXPECT_EQ(handle, consumer.handle());
328 ASSERT_EQ(1U, consumer.result().size());
329 EXPECT_EQ(profile, *consumer.result()[0]);
330 STLDeleteElements(&consumer.result());
332 // Check that GUID-based notification was sent.
333 const AutofillProfileChange expected_change(
334 AutofillProfileChange::REMOVE, profile.guid(), NULL);
335 EXPECT_CALL(observer_, AutofillProfileChanged(expected_change))
336 .WillOnce(SignalEvent(&done_event_));
338 // Remove the profile.
339 wds_->RemoveAutofillProfile(profile.guid());
340 done_event_.TimedWait(test_timeout_);
342 // Check that it was removed.
343 AutofillWebDataServiceConsumer<std::vector<AutofillProfile*> > consumer2;
344 WebDataServiceBase::Handle handle2 = wds_->GetAutofillProfiles(&consumer2);
345 base::MessageLoop::current()->Run();
346 EXPECT_EQ(handle2, consumer2.handle());
347 ASSERT_EQ(0U, consumer2.result().size());
350 TEST_F(WebDataServiceAutofillTest, ProfileUpdate) {
351 // The GUIDs are alphabetical for easier testing.
352 AutofillProfile profile1("6141084B-72D7-4B73-90CF-3D6AC154673B",
353 "http://example.com");
354 profile1.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Abe"));
355 AutofillProfile profile2("087151C8-6AB1-487C-9095-28E80BE5DA15",
356 "http://example.com");
357 profile2.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Alice"));
359 EXPECT_CALL(observer_, AutofillProfileChanged(_))
360 .WillOnce(DoDefault())
361 .WillOnce(SignalEvent(&done_event_));
363 wds_->AddAutofillProfile(profile1);
364 wds_->AddAutofillProfile(profile2);
365 done_event_.TimedWait(test_timeout_);
367 // Check that they were added.
368 AutofillWebDataServiceConsumer<std::vector<AutofillProfile*> > consumer;
369 WebDataServiceBase::Handle handle = wds_->GetAutofillProfiles(&consumer);
370 base::MessageLoop::current()->Run();
371 EXPECT_EQ(handle, consumer.handle());
372 ASSERT_EQ(2U, consumer.result().size());
373 EXPECT_EQ(profile2, *consumer.result()[0]);
374 EXPECT_EQ(profile1, *consumer.result()[1]);
375 STLDeleteElements(&consumer.result());
377 AutofillProfile profile2_changed(profile2);
378 profile2_changed.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Bill"));
379 const AutofillProfileChange expected_change(
380 AutofillProfileChange::UPDATE, profile2.guid(), &profile2_changed);
382 EXPECT_CALL(observer_, AutofillProfileChanged(expected_change))
383 .WillOnce(SignalEvent(&done_event_));
385 // Update the profile.
386 wds_->UpdateAutofillProfile(profile2_changed);
387 done_event_.TimedWait(test_timeout_);
389 // Check that the updates were made.
390 AutofillWebDataServiceConsumer<std::vector<AutofillProfile*> > consumer2;
391 WebDataServiceBase::Handle handle2 = wds_->GetAutofillProfiles(&consumer2);
392 base::MessageLoop::current()->Run();
393 EXPECT_EQ(handle2, consumer2.handle());
394 ASSERT_EQ(2U, consumer2.result().size());
395 EXPECT_EQ(profile2_changed, *consumer2.result()[0]);
396 EXPECT_NE(profile2, *consumer2.result()[0]);
397 EXPECT_EQ(profile1, *consumer2.result()[1]);
398 STLDeleteElements(&consumer2.result());
401 TEST_F(WebDataServiceAutofillTest, CreditAdd) {
403 wds_->AddCreditCard(card);
404 WaitForDatabaseThread();
406 // Check that it was added.
407 AutofillWebDataServiceConsumer<std::vector<CreditCard*> > consumer;
408 WebDataServiceBase::Handle handle = wds_->GetCreditCards(&consumer);
409 base::MessageLoop::current()->Run();
410 EXPECT_EQ(handle, consumer.handle());
411 ASSERT_EQ(1U, consumer.result().size());
412 EXPECT_EQ(card, *consumer.result()[0]);
413 STLDeleteElements(&consumer.result());
416 TEST_F(WebDataServiceAutofillTest, CreditCardRemove) {
417 CreditCard credit_card;
419 // Add a credit card.
420 wds_->AddCreditCard(credit_card);
421 WaitForDatabaseThread();
423 // Check that it was added.
424 AutofillWebDataServiceConsumer<std::vector<CreditCard*> > consumer;
425 WebDataServiceBase::Handle handle = wds_->GetCreditCards(&consumer);
426 base::MessageLoop::current()->Run();
427 EXPECT_EQ(handle, consumer.handle());
428 ASSERT_EQ(1U, consumer.result().size());
429 EXPECT_EQ(credit_card, *consumer.result()[0]);
430 STLDeleteElements(&consumer.result());
432 // Remove the credit card.
433 wds_->RemoveCreditCard(credit_card.guid());
434 WaitForDatabaseThread();
436 // Check that it was removed.
437 AutofillWebDataServiceConsumer<std::vector<CreditCard*> > consumer2;
438 WebDataServiceBase::Handle handle2 = wds_->GetCreditCards(&consumer2);
439 base::MessageLoop::current()->Run();
440 EXPECT_EQ(handle2, consumer2.handle());
441 ASSERT_EQ(0U, consumer2.result().size());
444 TEST_F(WebDataServiceAutofillTest, CreditUpdate) {
445 CreditCard card1("E4D2662E-5E16-44F3-AF5A-5A77FAE4A6F3",
446 "https://ejemplo.mx");
447 card1.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Abe"));
448 CreditCard card2("B9C52112-BD5F-4080-84E1-C651D2CB90E2",
449 "https://example.com");
450 card2.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Alice"));
452 wds_->AddCreditCard(card1);
453 wds_->AddCreditCard(card2);
454 WaitForDatabaseThread();
456 // Check that they got added.
457 AutofillWebDataServiceConsumer<std::vector<CreditCard*> > consumer;
458 WebDataServiceBase::Handle handle = wds_->GetCreditCards(&consumer);
459 base::MessageLoop::current()->Run();
460 EXPECT_EQ(handle, consumer.handle());
461 ASSERT_EQ(2U, consumer.result().size());
462 EXPECT_EQ(card2, *consumer.result()[0]);
463 EXPECT_EQ(card1, *consumer.result()[1]);
464 STLDeleteElements(&consumer.result());
466 CreditCard card2_changed(card2);
467 card2_changed.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Bill"));
469 wds_->UpdateCreditCard(card2_changed);
470 WaitForDatabaseThread();
472 // Check that the updates were made.
473 AutofillWebDataServiceConsumer<std::vector<CreditCard*> > consumer2;
474 WebDataServiceBase::Handle handle2 = wds_->GetCreditCards(&consumer2);
475 base::MessageLoop::current()->Run();
476 EXPECT_EQ(handle2, consumer2.handle());
477 ASSERT_EQ(2U, consumer2.result().size());
478 EXPECT_NE(card2, *consumer2.result()[0]);
479 EXPECT_EQ(card2_changed, *consumer2.result()[0]);
480 EXPECT_EQ(card1, *consumer2.result()[1]);
481 STLDeleteElements(&consumer2.result());
484 TEST_F(WebDataServiceAutofillTest, AutofillRemoveModifiedBetween) {
486 EXPECT_CALL(observer_, AutofillProfileChanged(_))
487 .WillOnce(SignalEvent(&done_event_));
488 AutofillProfile profile;
489 wds_->AddAutofillProfile(profile);
490 done_event_.TimedWait(test_timeout_);
492 // Check that it was added.
493 AutofillWebDataServiceConsumer<std::vector<AutofillProfile*> >
495 WebDataServiceBase::Handle handle =
496 wds_->GetAutofillProfiles(&profile_consumer);
497 base::MessageLoop::current()->Run();
498 EXPECT_EQ(handle, profile_consumer.handle());
499 ASSERT_EQ(1U, profile_consumer.result().size());
500 EXPECT_EQ(profile, *profile_consumer.result()[0]);
501 STLDeleteElements(&profile_consumer.result());
503 // Add a credit card.
504 CreditCard credit_card;
505 wds_->AddCreditCard(credit_card);
506 WaitForDatabaseThread();
508 // Check that it was added.
509 AutofillWebDataServiceConsumer<std::vector<CreditCard*> > card_consumer;
510 handle = wds_->GetCreditCards(&card_consumer);
511 base::MessageLoop::current()->Run();
512 EXPECT_EQ(handle, card_consumer.handle());
513 ASSERT_EQ(1U, card_consumer.result().size());
514 EXPECT_EQ(credit_card, *card_consumer.result()[0]);
515 STLDeleteElements(&card_consumer.result());
517 // Check that GUID-based notification was sent for the profile.
518 const AutofillProfileChange expected_profile_change(
519 AutofillProfileChange::REMOVE, profile.guid(), NULL);
520 EXPECT_CALL(observer_, AutofillProfileChanged(expected_profile_change))
521 .WillOnce(SignalEvent(&done_event_));
523 // Remove the profile using time range of "all time".
524 wds_->RemoveAutofillDataModifiedBetween(Time(), Time());
525 done_event_.TimedWait(test_timeout_);
526 WaitForDatabaseThread();
528 // Check that the profile was removed.
529 AutofillWebDataServiceConsumer<std::vector<AutofillProfile*> >
531 WebDataServiceBase::Handle handle2 =
532 wds_->GetAutofillProfiles(&profile_consumer2);
533 base::MessageLoop::current()->Run();
534 EXPECT_EQ(handle2, profile_consumer2.handle());
535 ASSERT_EQ(0U, profile_consumer2.result().size());
537 // Check that the credit card was removed.
538 AutofillWebDataServiceConsumer<std::vector<CreditCard*> > card_consumer2;
539 handle2 = wds_->GetCreditCards(&card_consumer2);
540 base::MessageLoop::current()->Run();
541 EXPECT_EQ(handle2, card_consumer2.handle());
542 ASSERT_EQ(0U, card_consumer2.result().size());
545 } // namespace autofill