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"
9 #include "base/files/scoped_temp_dir.h"
10 #include "base/memory/ref_counted.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/memory/scoped_vector.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/stl_util.h"
15 #include "base/strings/string16.h"
16 #include "base/strings/string_util.h"
17 #include "base/strings/utf_string_conversions.h"
18 #include "base/synchronization/waitable_event.h"
19 #include "base/time/time.h"
20 #include "components/autofill/core/browser/autofill_country.h"
21 #include "components/autofill/core/browser/autofill_profile.h"
22 #include "components/autofill/core/browser/credit_card.h"
23 #include "components/autofill/core/browser/webdata/autofill_change.h"
24 #include "components/autofill/core/browser/webdata/autofill_entry.h"
25 #include "components/autofill/core/browser/webdata/autofill_table.h"
26 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
27 #include "components/autofill/core/browser/webdata/autofill_webdata_service_observer.h"
28 #include "components/autofill/core/common/form_field_data.h"
29 #include "components/webdata/common/web_data_results.h"
30 #include "components/webdata/common/web_data_service_base.h"
31 #include "components/webdata/common/web_data_service_consumer.h"
32 #include "components/webdata/common/web_database_service.h"
33 #include "content/public/test/test_browser_thread.h"
34 #include "testing/gmock/include/gmock/gmock.h"
35 #include "testing/gtest/include/gtest/gtest.h"
38 using base::TimeDelta;
39 using base::WaitableEvent;
40 using content::BrowserThread;
42 using testing::DoDefault;
43 using testing::ElementsAreArray;
44 using testing::Pointee;
45 using testing::Property;
50 class AutofillWebDataServiceConsumer: public WebDataServiceConsumer {
52 AutofillWebDataServiceConsumer() : handle_(0) {}
53 virtual ~AutofillWebDataServiceConsumer() {}
55 virtual void OnWebDataServiceRequestDone(WebDataServiceBase::Handle handle,
56 const WDTypedResult* result) {
57 using content::BrowserThread;
58 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
60 const WDResult<T>* wrapped_result =
61 static_cast<const WDResult<T>*>(result);
62 result_ = wrapped_result->GetValue();
64 base::MessageLoop::current()->Quit();
67 WebDataServiceBase::Handle handle() { return handle_; }
68 T& result() { return result_; }
71 WebDataServiceBase::Handle handle_;
73 DISALLOW_COPY_AND_ASSIGN(AutofillWebDataServiceConsumer);
80 static const int kWebDataServiceTimeoutSeconds = 8;
82 ACTION_P(SignalEvent, event) {
86 class MockAutofillWebDataServiceObserver
87 : public AutofillWebDataServiceObserverOnDBThread {
89 MOCK_METHOD1(AutofillEntriesChanged,
90 void(const AutofillChangeList& changes));
91 MOCK_METHOD1(AutofillProfileChanged,
92 void(const AutofillProfileChange& change));
95 class WebDataServiceTest : public testing::Test {
98 : ui_thread_(BrowserThread::UI, &message_loop_),
99 db_thread_(BrowserThread::DB) {}
102 virtual void SetUp() {
105 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
106 base::FilePath path = temp_dir_.path().AppendASCII("TestWebDB");
108 wdbs_ = new WebDatabaseService(
110 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
111 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB));
112 wdbs_->AddTable(scoped_ptr<WebDatabaseTable>(new AutofillTable("en-US")));
113 wdbs_->LoadDatabase();
115 wds_ = new AutofillWebDataService(
117 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
118 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB),
119 WebDataServiceBase::ProfileErrorCallback());
123 virtual void TearDown() {
124 wds_->ShutdownOnUIThread();
125 wdbs_->ShutdownDatabase();
128 WaitForDatabaseThread();
130 base::MessageLoop::current()->PostTask(FROM_HERE,
131 base::MessageLoop::QuitClosure());
132 base::MessageLoop::current()->Run();
136 void WaitForDatabaseThread() {
137 base::WaitableEvent done(false, false);
138 BrowserThread::PostTask(
141 base::Bind(&base::WaitableEvent::Signal, base::Unretained(&done)));
145 base::MessageLoopForUI message_loop_;
146 content::TestBrowserThread ui_thread_;
147 content::TestBrowserThread db_thread_;
148 base::FilePath profile_dir_;
149 scoped_refptr<AutofillWebDataService> wds_;
150 scoped_refptr<WebDatabaseService> wdbs_;
151 base::ScopedTempDir temp_dir_;
154 class WebDataServiceAutofillTest : public WebDataServiceTest {
156 WebDataServiceAutofillTest()
157 : WebDataServiceTest(),
160 test_timeout_(TimeDelta::FromSeconds(kWebDataServiceTimeoutSeconds)),
161 done_event_(false, false) {}
164 virtual void SetUp() {
165 WebDataServiceTest::SetUp();
166 name1_ = ASCIIToUTF16("name1");
167 name2_ = ASCIIToUTF16("name2");
168 value1_ = ASCIIToUTF16("value1");
169 value2_ = ASCIIToUTF16("value2");
171 void(AutofillWebDataService::*add_observer_func)(
172 AutofillWebDataServiceObserverOnDBThread*) =
173 &AutofillWebDataService::AddObserver;
174 BrowserThread::PostTask(
177 base::Bind(add_observer_func, wds_, &observer_));
178 WaitForDatabaseThread();
181 virtual void TearDown() {
182 void(AutofillWebDataService::*remove_observer_func)(
183 AutofillWebDataServiceObserverOnDBThread*) =
184 &AutofillWebDataService::RemoveObserver;
185 BrowserThread::PostTask(
188 base::Bind(remove_observer_func, wds_, &observer_));
189 WaitForDatabaseThread();
191 WebDataServiceTest::TearDown();
194 void AppendFormField(const base::string16& name,
195 const base::string16& value,
196 std::vector<FormFieldData>* form_fields) {
200 form_fields->push_back(field);
203 base::string16 name1_;
204 base::string16 name2_;
205 base::string16 value1_;
206 base::string16 value2_;
207 int unique_id1_, unique_id2_;
208 const TimeDelta test_timeout_;
209 testing::NiceMock<MockAutofillWebDataServiceObserver> observer_;
210 WaitableEvent done_event_;
213 TEST_F(WebDataServiceAutofillTest, FormFillAdd) {
214 const AutofillChange expected_changes[] = {
215 AutofillChange(AutofillChange::ADD, AutofillKey(name1_, value1_)),
216 AutofillChange(AutofillChange::ADD, AutofillKey(name2_, value2_))
219 // This will verify that the correct notification is triggered,
220 // passing the correct list of autofill keys in the details.
221 EXPECT_CALL(observer_,
222 AutofillEntriesChanged(ElementsAreArray(expected_changes)))
223 .WillOnce(SignalEvent(&done_event_));
225 std::vector<FormFieldData> form_fields;
226 AppendFormField(name1_, value1_, &form_fields);
227 AppendFormField(name2_, value2_, &form_fields);
228 wds_->AddFormFields(form_fields);
230 // The event will be signaled when the mock observer is notified.
231 done_event_.TimedWait(test_timeout_);
233 AutofillWebDataServiceConsumer<std::vector<base::string16> > consumer;
234 WebDataServiceBase::Handle handle;
235 static const int limit = 10;
236 handle = wds_->GetFormValuesForElementName(
237 name1_, base::string16(), limit, &consumer);
239 // The message loop will exit when the consumer is called.
240 base::MessageLoop::current()->Run();
242 EXPECT_EQ(handle, consumer.handle());
243 ASSERT_EQ(1U, consumer.result().size());
244 EXPECT_EQ(value1_, consumer.result()[0]);
247 TEST_F(WebDataServiceAutofillTest, FormFillRemoveOne) {
248 // First add some values to autofill.
249 EXPECT_CALL(observer_, AutofillEntriesChanged(_))
250 .WillOnce(SignalEvent(&done_event_));
251 std::vector<FormFieldData> form_fields;
252 AppendFormField(name1_, value1_, &form_fields);
253 wds_->AddFormFields(form_fields);
255 // The event will be signaled when the mock observer is notified.
256 done_event_.TimedWait(test_timeout_);
258 // This will verify that the correct notification is triggered,
259 // passing the correct list of autofill keys in the details.
260 const AutofillChange expected_changes[] = {
261 AutofillChange(AutofillChange::REMOVE, AutofillKey(name1_, value1_))
263 EXPECT_CALL(observer_,
264 AutofillEntriesChanged(ElementsAreArray(expected_changes)))
265 .WillOnce(SignalEvent(&done_event_));
266 wds_->RemoveFormValueForElementName(name1_, value1_);
268 // The event will be signaled when the mock observer is notified.
269 done_event_.TimedWait(test_timeout_);
272 TEST_F(WebDataServiceAutofillTest, FormFillRemoveMany) {
273 TimeDelta one_day(TimeDelta::FromDays(1));
274 Time t = Time::Now();
276 EXPECT_CALL(observer_, AutofillEntriesChanged(_))
277 .WillOnce(SignalEvent(&done_event_));
279 std::vector<FormFieldData> form_fields;
280 AppendFormField(name1_, value1_, &form_fields);
281 AppendFormField(name2_, value2_, &form_fields);
282 wds_->AddFormFields(form_fields);
284 // The event will be signaled when the mock observer is notified.
285 done_event_.TimedWait(test_timeout_);
287 // This will verify that the correct notification is triggered,
288 // passing the correct list of autofill keys in the details.
289 const AutofillChange expected_changes[] = {
290 AutofillChange(AutofillChange::REMOVE, AutofillKey(name1_, value1_)),
291 AutofillChange(AutofillChange::REMOVE, AutofillKey(name2_, value2_))
293 EXPECT_CALL(observer_,
294 AutofillEntriesChanged(ElementsAreArray(expected_changes)))
295 .WillOnce(SignalEvent(&done_event_));
296 wds_->RemoveFormElementsAddedBetween(t, t + one_day);
298 // The event will be signaled when the mock observer is notified.
299 done_event_.TimedWait(test_timeout_);
302 TEST_F(WebDataServiceAutofillTest, ProfileAdd) {
303 AutofillProfile profile;
305 // Check that GUID-based notification was sent.
306 const AutofillProfileChange expected_change(
307 AutofillProfileChange::ADD, profile.guid(), &profile);
308 EXPECT_CALL(observer_, AutofillProfileChanged(expected_change))
309 .WillOnce(SignalEvent(&done_event_));
311 wds_->AddAutofillProfile(profile);
312 done_event_.TimedWait(test_timeout_);
314 // Check that it was added.
315 AutofillWebDataServiceConsumer<std::vector<AutofillProfile*> > consumer;
316 WebDataServiceBase::Handle handle = wds_->GetAutofillProfiles(&consumer);
317 base::MessageLoop::current()->Run();
318 EXPECT_EQ(handle, consumer.handle());
319 ASSERT_EQ(1U, consumer.result().size());
320 EXPECT_EQ(profile, *consumer.result()[0]);
321 STLDeleteElements(&consumer.result());
324 TEST_F(WebDataServiceAutofillTest, ProfileRemove) {
325 AutofillProfile profile;
328 EXPECT_CALL(observer_, AutofillProfileChanged(_))
329 .WillOnce(SignalEvent(&done_event_));
330 wds_->AddAutofillProfile(profile);
331 done_event_.TimedWait(test_timeout_);
333 // Check that it was added.
334 AutofillWebDataServiceConsumer<std::vector<AutofillProfile*> > consumer;
335 WebDataServiceBase::Handle handle = wds_->GetAutofillProfiles(&consumer);
336 base::MessageLoop::current()->Run();
337 EXPECT_EQ(handle, consumer.handle());
338 ASSERT_EQ(1U, consumer.result().size());
339 EXPECT_EQ(profile, *consumer.result()[0]);
340 STLDeleteElements(&consumer.result());
342 // Check that GUID-based notification was sent.
343 const AutofillProfileChange expected_change(
344 AutofillProfileChange::REMOVE, profile.guid(), NULL);
345 EXPECT_CALL(observer_, AutofillProfileChanged(expected_change))
346 .WillOnce(SignalEvent(&done_event_));
348 // Remove the profile.
349 wds_->RemoveAutofillProfile(profile.guid());
350 done_event_.TimedWait(test_timeout_);
352 // Check that it was removed.
353 AutofillWebDataServiceConsumer<std::vector<AutofillProfile*> > consumer2;
354 WebDataServiceBase::Handle handle2 = wds_->GetAutofillProfiles(&consumer2);
355 base::MessageLoop::current()->Run();
356 EXPECT_EQ(handle2, consumer2.handle());
357 ASSERT_EQ(0U, consumer2.result().size());
360 TEST_F(WebDataServiceAutofillTest, ProfileUpdate) {
361 AutofillProfile profile1;
362 profile1.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Abe"));
363 AutofillProfile profile2;
364 profile2.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Alice"));
366 EXPECT_CALL(observer_, AutofillProfileChanged(_))
367 .WillOnce(DoDefault())
368 .WillOnce(SignalEvent(&done_event_));
370 wds_->AddAutofillProfile(profile1);
371 wds_->AddAutofillProfile(profile2);
372 done_event_.TimedWait(test_timeout_);
374 // Check that they were added.
375 AutofillWebDataServiceConsumer<std::vector<AutofillProfile*> > consumer;
376 WebDataServiceBase::Handle handle = wds_->GetAutofillProfiles(&consumer);
377 base::MessageLoop::current()->Run();
378 EXPECT_EQ(handle, consumer.handle());
379 ASSERT_EQ(2U, consumer.result().size());
380 EXPECT_EQ(profile1, *consumer.result()[0]);
381 EXPECT_EQ(profile2, *consumer.result()[1]);
382 STLDeleteElements(&consumer.result());
384 AutofillProfile profile1_changed(profile1);
385 profile1_changed.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Bill"));
386 const AutofillProfileChange expected_change(
387 AutofillProfileChange::UPDATE, profile1.guid(), &profile1_changed);
389 EXPECT_CALL(observer_, AutofillProfileChanged(expected_change))
390 .WillOnce(SignalEvent(&done_event_));
392 // Update the profile.
393 wds_->UpdateAutofillProfile(profile1_changed);
394 done_event_.TimedWait(test_timeout_);
396 // Check that the updates were made.
397 AutofillWebDataServiceConsumer<std::vector<AutofillProfile*> > consumer2;
398 WebDataServiceBase::Handle handle2 = wds_->GetAutofillProfiles(&consumer2);
399 base::MessageLoop::current()->Run();
400 EXPECT_EQ(handle2, consumer2.handle());
401 ASSERT_EQ(2U, consumer2.result().size());
402 EXPECT_NE(profile1, *consumer2.result()[0]);
403 EXPECT_EQ(profile1_changed, *consumer2.result()[0]);
404 EXPECT_EQ(profile2, *consumer2.result()[1]);
405 STLDeleteElements(&consumer2.result());
408 TEST_F(WebDataServiceAutofillTest, CreditAdd) {
410 wds_->AddCreditCard(card);
411 WaitForDatabaseThread();
413 // Check that it was added.
414 AutofillWebDataServiceConsumer<std::vector<CreditCard*> > consumer;
415 WebDataServiceBase::Handle handle = wds_->GetCreditCards(&consumer);
416 base::MessageLoop::current()->Run();
417 EXPECT_EQ(handle, consumer.handle());
418 ASSERT_EQ(1U, consumer.result().size());
419 EXPECT_EQ(card, *consumer.result()[0]);
420 STLDeleteElements(&consumer.result());
423 TEST_F(WebDataServiceAutofillTest, CreditCardRemove) {
424 CreditCard credit_card;
426 // Add a credit card.
427 wds_->AddCreditCard(credit_card);
428 WaitForDatabaseThread();
430 // Check that it was added.
431 AutofillWebDataServiceConsumer<std::vector<CreditCard*> > consumer;
432 WebDataServiceBase::Handle handle = wds_->GetCreditCards(&consumer);
433 base::MessageLoop::current()->Run();
434 EXPECT_EQ(handle, consumer.handle());
435 ASSERT_EQ(1U, consumer.result().size());
436 EXPECT_EQ(credit_card, *consumer.result()[0]);
437 STLDeleteElements(&consumer.result());
439 // Remove the credit card.
440 wds_->RemoveCreditCard(credit_card.guid());
441 WaitForDatabaseThread();
443 // Check that it was removed.
444 AutofillWebDataServiceConsumer<std::vector<CreditCard*> > consumer2;
445 WebDataServiceBase::Handle handle2 = wds_->GetCreditCards(&consumer2);
446 base::MessageLoop::current()->Run();
447 EXPECT_EQ(handle2, consumer2.handle());
448 ASSERT_EQ(0U, consumer2.result().size());
451 TEST_F(WebDataServiceAutofillTest, CreditUpdate) {
453 card1.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Abe"));
455 card2.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Alice"));
457 wds_->AddCreditCard(card1);
458 wds_->AddCreditCard(card2);
459 WaitForDatabaseThread();
461 // Check that they got added.
462 AutofillWebDataServiceConsumer<std::vector<CreditCard*> > consumer;
463 WebDataServiceBase::Handle handle = wds_->GetCreditCards(&consumer);
464 base::MessageLoop::current()->Run();
465 EXPECT_EQ(handle, consumer.handle());
466 ASSERT_EQ(2U, consumer.result().size());
467 EXPECT_EQ(card1, *consumer.result()[0]);
468 EXPECT_EQ(card2, *consumer.result()[1]);
469 STLDeleteElements(&consumer.result());
471 CreditCard card1_changed(card1);
472 card1_changed.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Bill"));
474 wds_->UpdateCreditCard(card1_changed);
475 WaitForDatabaseThread();
477 // Check that the updates were made.
478 AutofillWebDataServiceConsumer<std::vector<CreditCard*> > consumer2;
479 WebDataServiceBase::Handle handle2 = wds_->GetCreditCards(&consumer2);
480 base::MessageLoop::current()->Run();
481 EXPECT_EQ(handle2, consumer2.handle());
482 ASSERT_EQ(2U, consumer2.result().size());
483 EXPECT_NE(card1, *consumer2.result()[0]);
484 EXPECT_EQ(card1_changed, *consumer2.result()[0]);
485 EXPECT_EQ(card2, *consumer2.result()[1]);
486 STLDeleteElements(&consumer2.result());
489 TEST_F(WebDataServiceAutofillTest, AutofillRemoveModifiedBetween) {
491 EXPECT_CALL(observer_, AutofillProfileChanged(_))
492 .WillOnce(SignalEvent(&done_event_));
493 AutofillProfile profile;
494 wds_->AddAutofillProfile(profile);
495 done_event_.TimedWait(test_timeout_);
497 // Check that it was added.
498 AutofillWebDataServiceConsumer<std::vector<AutofillProfile*> >
500 WebDataServiceBase::Handle handle =
501 wds_->GetAutofillProfiles(&profile_consumer);
502 base::MessageLoop::current()->Run();
503 EXPECT_EQ(handle, profile_consumer.handle());
504 ASSERT_EQ(1U, profile_consumer.result().size());
505 EXPECT_EQ(profile, *profile_consumer.result()[0]);
506 STLDeleteElements(&profile_consumer.result());
508 // Add a credit card.
509 CreditCard credit_card;
510 wds_->AddCreditCard(credit_card);
511 WaitForDatabaseThread();
513 // Check that it was added.
514 AutofillWebDataServiceConsumer<std::vector<CreditCard*> > card_consumer;
515 handle = wds_->GetCreditCards(&card_consumer);
516 base::MessageLoop::current()->Run();
517 EXPECT_EQ(handle, card_consumer.handle());
518 ASSERT_EQ(1U, card_consumer.result().size());
519 EXPECT_EQ(credit_card, *card_consumer.result()[0]);
520 STLDeleteElements(&card_consumer.result());
522 // Check that GUID-based notification was sent for the profile.
523 const AutofillProfileChange expected_profile_change(
524 AutofillProfileChange::REMOVE, profile.guid(), NULL);
525 EXPECT_CALL(observer_, AutofillProfileChanged(expected_profile_change))
526 .WillOnce(SignalEvent(&done_event_));
528 // Remove the profile using time range of "all time".
529 wds_->RemoveAutofillDataModifiedBetween(Time(), Time());
530 done_event_.TimedWait(test_timeout_);
531 WaitForDatabaseThread();
533 // Check that the profile was removed.
534 AutofillWebDataServiceConsumer<std::vector<AutofillProfile*> >
536 WebDataServiceBase::Handle handle2 =
537 wds_->GetAutofillProfiles(&profile_consumer2);
538 base::MessageLoop::current()->Run();
539 EXPECT_EQ(handle2, profile_consumer2.handle());
540 ASSERT_EQ(0U, profile_consumer2.result().size());
542 // Check that the credit card was removed.
543 AutofillWebDataServiceConsumer<std::vector<CreditCard*> > card_consumer2;
544 handle2 = wds_->GetCreditCards(&card_consumer2);
545 base::MessageLoop::current()->Run();
546 EXPECT_EQ(handle2, card_consumer2.handle());
547 ASSERT_EQ(0U, card_consumer2.result().size());
550 } // namespace autofill