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. 4 5#include <string> 6#include <vector> 7 8#include "base/basictypes.h" 9#include "base/bind.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" 37 38using base::ASCIIToUTF16; 39using base::Time; 40using base::TimeDelta; 41using base::WaitableEvent; 42using testing::_; 43using testing::DoDefault; 44using testing::ElementsAreArray; 45using testing::Pointee; 46using testing::Property; 47 48namespace { 49 50template <class T> 51class AutofillWebDataServiceConsumer: public WebDataServiceConsumer { 52 public: 53 AutofillWebDataServiceConsumer() : handle_(0) {} 54 virtual ~AutofillWebDataServiceConsumer() {} 55 56 virtual void OnWebDataServiceRequestDone(WebDataServiceBase::Handle handle, 57 const WDTypedResult* result) { 58 handle_ = handle; 59 const WDResult<T>* wrapped_result = 60 static_cast<const WDResult<T>*>(result); 61 result_ = wrapped_result->GetValue(); 62 63 base::MessageLoop::current()->Quit(); 64 } 65 66 WebDataServiceBase::Handle handle() { return handle_; } 67 T& result() { return result_; } 68 69 private: 70 WebDataServiceBase::Handle handle_; 71 T result_; 72 DISALLOW_COPY_AND_ASSIGN(AutofillWebDataServiceConsumer); 73}; 74 75} // namespace 76 77namespace autofill { 78 79static const int kWebDataServiceTimeoutSeconds = 8; 80 81ACTION_P(SignalEvent, event) { 82 event->Signal(); 83} 84 85class MockAutofillWebDataServiceObserver 86 : public AutofillWebDataServiceObserverOnDBThread { 87 public: 88 MOCK_METHOD1(AutofillEntriesChanged, 89 void(const AutofillChangeList& changes)); 90 MOCK_METHOD1(AutofillProfileChanged, 91 void(const AutofillProfileChange& change)); 92}; 93 94class WebDataServiceTest : public testing::Test { 95 public: 96 WebDataServiceTest() : db_thread_("DBThread") {} 97 98 protected: 99 virtual void SetUp() { 100 db_thread_.Start(); 101 102 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 103 base::FilePath path = temp_dir_.path().AppendASCII("TestWebDB"); 104 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(); 110 111 wds_ = 112 new AutofillWebDataService(wdbs_, 113 base::MessageLoopProxy::current(), 114 db_thread_.message_loop_proxy(), 115 WebDataServiceBase::ProfileErrorCallback()); 116 wds_->Init(); 117 } 118 119 virtual void TearDown() { 120 wds_->ShutdownOnUIThread(); 121 wdbs_->ShutdownDatabase(); 122 wds_ = NULL; 123 wdbs_ = NULL; 124 WaitForDatabaseThread(); 125 126 base::MessageLoop::current()->PostTask(FROM_HERE, 127 base::MessageLoop::QuitClosure()); 128 base::MessageLoop::current()->Run(); 129 db_thread_.Stop(); 130 } 131 132 void WaitForDatabaseThread() { 133 base::WaitableEvent done(false, false); 134 db_thread_.message_loop()->PostTask( 135 FROM_HERE, 136 base::Bind(&base::WaitableEvent::Signal, base::Unretained(&done))); 137 done.Wait(); 138 } 139 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_; 146}; 147 148class WebDataServiceAutofillTest : public WebDataServiceTest { 149 public: 150 WebDataServiceAutofillTest() 151 : WebDataServiceTest(), 152 unique_id1_(1), 153 unique_id2_(2), 154 test_timeout_(TimeDelta::FromSeconds(kWebDataServiceTimeoutSeconds)), 155 done_event_(false, false) {} 156 157 protected: 158 virtual void SetUp() { 159 WebDataServiceTest::SetUp(); 160 name1_ = ASCIIToUTF16("name1"); 161 name2_ = ASCIIToUTF16("name2"); 162 value1_ = ASCIIToUTF16("value1"); 163 value2_ = ASCIIToUTF16("value2"); 164 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(); 171 } 172 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(); 180 181 WebDataServiceTest::TearDown(); 182 } 183 184 void AppendFormField(const base::string16& name, 185 const base::string16& value, 186 std::vector<FormFieldData>* form_fields) { 187 FormFieldData field; 188 field.name = name; 189 field.value = value; 190 form_fields->push_back(field); 191 } 192 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_; 201}; 202 203TEST_F(WebDataServiceAutofillTest, FormFillAdd) { 204 const AutofillChange expected_changes[] = { 205 AutofillChange(AutofillChange::ADD, AutofillKey(name1_, value1_)), 206 AutofillChange(AutofillChange::ADD, AutofillKey(name2_, value2_)) 207 }; 208 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_)); 214 215 std::vector<FormFieldData> form_fields; 216 AppendFormField(name1_, value1_, &form_fields); 217 AppendFormField(name2_, value2_, &form_fields); 218 wds_->AddFormFields(form_fields); 219 220 // The event will be signaled when the mock observer is notified. 221 done_event_.TimedWait(test_timeout_); 222 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); 228 229 // The message loop will exit when the consumer is called. 230 base::MessageLoop::current()->Run(); 231 232 EXPECT_EQ(handle, consumer.handle()); 233 ASSERT_EQ(1U, consumer.result().size()); 234 EXPECT_EQ(value1_, consumer.result()[0]); 235} 236 237TEST_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); 244 245 // The event will be signaled when the mock observer is notified. 246 done_event_.TimedWait(test_timeout_); 247 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_)) 252 }; 253 EXPECT_CALL(observer_, 254 AutofillEntriesChanged(ElementsAreArray(expected_changes))) 255 .WillOnce(SignalEvent(&done_event_)); 256 wds_->RemoveFormValueForElementName(name1_, value1_); 257 258 // The event will be signaled when the mock observer is notified. 259 done_event_.TimedWait(test_timeout_); 260} 261 262TEST_F(WebDataServiceAutofillTest, FormFillRemoveMany) { 263 TimeDelta one_day(TimeDelta::FromDays(1)); 264 Time t = Time::Now(); 265 266 EXPECT_CALL(observer_, AutofillEntriesChanged(_)) 267 .WillOnce(SignalEvent(&done_event_)); 268 269 std::vector<FormFieldData> form_fields; 270 AppendFormField(name1_, value1_, &form_fields); 271 AppendFormField(name2_, value2_, &form_fields); 272 wds_->AddFormFields(form_fields); 273 274 // The event will be signaled when the mock observer is notified. 275 done_event_.TimedWait(test_timeout_); 276 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_)) 282 }; 283 EXPECT_CALL(observer_, 284 AutofillEntriesChanged(ElementsAreArray(expected_changes))) 285 .WillOnce(SignalEvent(&done_event_)); 286 wds_->RemoveFormElementsAddedBetween(t, t + one_day); 287 288 // The event will be signaled when the mock observer is notified. 289 done_event_.TimedWait(test_timeout_); 290} 291 292TEST_F(WebDataServiceAutofillTest, ProfileAdd) { 293 AutofillProfile profile; 294 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_)); 300 301 wds_->AddAutofillProfile(profile); 302 done_event_.TimedWait(test_timeout_); 303 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()); 312} 313 314TEST_F(WebDataServiceAutofillTest, ProfileRemove) { 315 AutofillProfile profile; 316 317 // Add a profile. 318 EXPECT_CALL(observer_, AutofillProfileChanged(_)) 319 .WillOnce(SignalEvent(&done_event_)); 320 wds_->AddAutofillProfile(profile); 321 done_event_.TimedWait(test_timeout_); 322 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()); 331 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_)); 337 338 // Remove the profile. 339 wds_->RemoveAutofillProfile(profile.guid()); 340 done_event_.TimedWait(test_timeout_); 341 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()); 348} 349 350TEST_F(WebDataServiceAutofillTest, ProfileUpdate) { 351 // The GUIDs are alphabetical for easier testing. 352 AutofillProfile profile1("087151C8-6AB1-487C-9095-28E80BE5DA15", 353 "http://example.com"); 354 profile1.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Abe")); 355 AutofillProfile profile2("6141084B-72D7-4B73-90CF-3D6AC154673B", 356 "http://example.com"); 357 profile2.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Alice")); 358 359 EXPECT_CALL(observer_, AutofillProfileChanged(_)) 360 .WillOnce(DoDefault()) 361 .WillOnce(SignalEvent(&done_event_)); 362 363 wds_->AddAutofillProfile(profile1); 364 wds_->AddAutofillProfile(profile2); 365 done_event_.TimedWait(test_timeout_); 366 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(profile1, *consumer.result()[0]); 374 EXPECT_EQ(profile2, *consumer.result()[1]); 375 STLDeleteElements(&consumer.result()); 376 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); 381 382 EXPECT_CALL(observer_, AutofillProfileChanged(expected_change)) 383 .WillOnce(SignalEvent(&done_event_)); 384 385 // Update the profile. 386 wds_->UpdateAutofillProfile(profile2_changed); 387 done_event_.TimedWait(test_timeout_); 388 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(profile1, *consumer2.result()[0]); 396 EXPECT_EQ(profile2_changed, *consumer2.result()[1]); 397 EXPECT_NE(profile2, *consumer2.result()[1]); 398 STLDeleteElements(&consumer2.result()); 399} 400 401TEST_F(WebDataServiceAutofillTest, CreditAdd) { 402 CreditCard card; 403 wds_->AddCreditCard(card); 404 WaitForDatabaseThread(); 405 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()); 414} 415 416TEST_F(WebDataServiceAutofillTest, CreditCardRemove) { 417 CreditCard credit_card; 418 419 // Add a credit card. 420 wds_->AddCreditCard(credit_card); 421 WaitForDatabaseThread(); 422 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()); 431 432 // Remove the credit card. 433 wds_->RemoveCreditCard(credit_card.guid()); 434 WaitForDatabaseThread(); 435 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()); 442} 443 444TEST_F(WebDataServiceAutofillTest, CreditUpdate) { 445 CreditCard card1("B9C52112-BD5F-4080-84E1-C651D2CB90E2", 446 "https://ejemplo.mx"); 447 card1.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Abe")); 448 CreditCard card2("E4D2662E-5E16-44F3-AF5A-5A77FAE4A6F3", 449 "https://example.com"); 450 card2.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Alice")); 451 452 wds_->AddCreditCard(card1); 453 wds_->AddCreditCard(card2); 454 WaitForDatabaseThread(); 455 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(card1, *consumer.result()[0]); 463 EXPECT_EQ(card2, *consumer.result()[1]); 464 STLDeleteElements(&consumer.result()); 465 466 CreditCard card1_changed(card1); 467 card1_changed.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Bill")); 468 469 wds_->UpdateCreditCard(card1_changed); 470 WaitForDatabaseThread(); 471 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(card1, *consumer2.result()[0]); 479 EXPECT_EQ(card1_changed, *consumer2.result()[0]); 480 EXPECT_EQ(card2, *consumer2.result()[1]); 481 STLDeleteElements(&consumer2.result()); 482} 483 484TEST_F(WebDataServiceAutofillTest, AutofillRemoveModifiedBetween) { 485 // Add a profile. 486 EXPECT_CALL(observer_, AutofillProfileChanged(_)) 487 .WillOnce(SignalEvent(&done_event_)); 488 AutofillProfile profile; 489 wds_->AddAutofillProfile(profile); 490 done_event_.TimedWait(test_timeout_); 491 492 // Check that it was added. 493 AutofillWebDataServiceConsumer<std::vector<AutofillProfile*> > 494 profile_consumer; 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()); 502 503 // Add a credit card. 504 CreditCard credit_card; 505 wds_->AddCreditCard(credit_card); 506 WaitForDatabaseThread(); 507 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()); 516 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_)); 522 523 // Remove the profile using time range of "all time". 524 wds_->RemoveAutofillDataModifiedBetween(Time(), Time()); 525 done_event_.TimedWait(test_timeout_); 526 WaitForDatabaseThread(); 527 528 // Check that the profile was removed. 529 AutofillWebDataServiceConsumer<std::vector<AutofillProfile*> > 530 profile_consumer2; 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()); 536 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()); 543} 544 545} // namespace autofill 546