web_data_service_unittest.cc revision 0f1bc08d4cfcc34181b0b5cbf065c40f687bf740
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/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" 36 37using base::Time; 38using base::TimeDelta; 39using base::WaitableEvent; 40using content::BrowserThread; 41using testing::_; 42using testing::DoDefault; 43using testing::ElementsAreArray; 44using testing::Pointee; 45using testing::Property; 46 47namespace { 48 49template <class T> 50class AutofillWebDataServiceConsumer: public WebDataServiceConsumer { 51 public: 52 AutofillWebDataServiceConsumer() : handle_(0) {} 53 virtual ~AutofillWebDataServiceConsumer() {} 54 55 virtual void OnWebDataServiceRequestDone(WebDataServiceBase::Handle handle, 56 const WDTypedResult* result) { 57 using content::BrowserThread; 58 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 59 handle_ = handle; 60 const WDResult<T>* wrapped_result = 61 static_cast<const WDResult<T>*>(result); 62 result_ = wrapped_result->GetValue(); 63 64 base::MessageLoop::current()->Quit(); 65 } 66 67 WebDataServiceBase::Handle handle() { return handle_; } 68 T& result() { return result_; } 69 70 private: 71 WebDataServiceBase::Handle handle_; 72 T result_; 73 DISALLOW_COPY_AND_ASSIGN(AutofillWebDataServiceConsumer); 74}; 75 76} // namespace 77 78namespace autofill { 79 80static const int kWebDataServiceTimeoutSeconds = 8; 81 82ACTION_P(SignalEvent, event) { 83 event->Signal(); 84} 85 86class MockAutofillWebDataServiceObserver 87 : public AutofillWebDataServiceObserverOnDBThread { 88 public: 89 MOCK_METHOD1(AutofillEntriesChanged, 90 void(const AutofillChangeList& changes)); 91 MOCK_METHOD1(AutofillProfileChanged, 92 void(const AutofillProfileChange& change)); 93}; 94 95class WebDataServiceTest : public testing::Test { 96 public: 97 WebDataServiceTest() 98 : ui_thread_(BrowserThread::UI, &message_loop_), 99 db_thread_(BrowserThread::DB) {} 100 101 protected: 102 virtual void SetUp() { 103 db_thread_.Start(); 104 105 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 106 base::FilePath path = temp_dir_.path().AppendASCII("TestWebDB"); 107 108 wdbs_ = new WebDatabaseService( 109 path, 110 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI), 111 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB)); 112 wdbs_->AddTable(scoped_ptr<WebDatabaseTable>(new AutofillTable("en-US"))); 113 wdbs_->LoadDatabase(); 114 115 wds_ = new AutofillWebDataService( 116 wdbs_, 117 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI), 118 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB), 119 WebDataServiceBase::ProfileErrorCallback()); 120 wds_->Init(); 121 } 122 123 virtual void TearDown() { 124 wds_->ShutdownOnUIThread(); 125 wdbs_->ShutdownDatabase(); 126 wds_ = NULL; 127 wdbs_ = NULL; 128 WaitForDatabaseThread(); 129 130 base::MessageLoop::current()->PostTask(FROM_HERE, 131 base::MessageLoop::QuitClosure()); 132 base::MessageLoop::current()->Run(); 133 db_thread_.Stop(); 134 } 135 136 void WaitForDatabaseThread() { 137 base::WaitableEvent done(false, false); 138 BrowserThread::PostTask( 139 BrowserThread::DB, 140 FROM_HERE, 141 base::Bind(&base::WaitableEvent::Signal, base::Unretained(&done))); 142 done.Wait(); 143 } 144 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_; 152}; 153 154class WebDataServiceAutofillTest : public WebDataServiceTest { 155 public: 156 WebDataServiceAutofillTest() 157 : WebDataServiceTest(), 158 unique_id1_(1), 159 unique_id2_(2), 160 test_timeout_(TimeDelta::FromSeconds(kWebDataServiceTimeoutSeconds)), 161 done_event_(false, false) {} 162 163 protected: 164 virtual void SetUp() { 165 WebDataServiceTest::SetUp(); 166 name1_ = ASCIIToUTF16("name1"); 167 name2_ = ASCIIToUTF16("name2"); 168 value1_ = ASCIIToUTF16("value1"); 169 value2_ = ASCIIToUTF16("value2"); 170 171 void(AutofillWebDataService::*add_observer_func)( 172 AutofillWebDataServiceObserverOnDBThread*) = 173 &AutofillWebDataService::AddObserver; 174 BrowserThread::PostTask( 175 BrowserThread::DB, 176 FROM_HERE, 177 base::Bind(add_observer_func, wds_, &observer_)); 178 WaitForDatabaseThread(); 179 } 180 181 virtual void TearDown() { 182 void(AutofillWebDataService::*remove_observer_func)( 183 AutofillWebDataServiceObserverOnDBThread*) = 184 &AutofillWebDataService::RemoveObserver; 185 BrowserThread::PostTask( 186 BrowserThread::DB, 187 FROM_HERE, 188 base::Bind(remove_observer_func, wds_, &observer_)); 189 WaitForDatabaseThread(); 190 191 WebDataServiceTest::TearDown(); 192 } 193 194 void AppendFormField(const base::string16& name, 195 const base::string16& value, 196 std::vector<FormFieldData>* form_fields) { 197 FormFieldData field; 198 field.name = name; 199 field.value = value; 200 form_fields->push_back(field); 201 } 202 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_; 211}; 212 213TEST_F(WebDataServiceAutofillTest, FormFillAdd) { 214 const AutofillChange expected_changes[] = { 215 AutofillChange(AutofillChange::ADD, AutofillKey(name1_, value1_)), 216 AutofillChange(AutofillChange::ADD, AutofillKey(name2_, value2_)) 217 }; 218 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_)); 224 225 std::vector<FormFieldData> form_fields; 226 AppendFormField(name1_, value1_, &form_fields); 227 AppendFormField(name2_, value2_, &form_fields); 228 wds_->AddFormFields(form_fields); 229 230 // The event will be signaled when the mock observer is notified. 231 done_event_.TimedWait(test_timeout_); 232 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); 238 239 // The message loop will exit when the consumer is called. 240 base::MessageLoop::current()->Run(); 241 242 EXPECT_EQ(handle, consumer.handle()); 243 ASSERT_EQ(1U, consumer.result().size()); 244 EXPECT_EQ(value1_, consumer.result()[0]); 245} 246 247TEST_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); 254 255 // The event will be signaled when the mock observer is notified. 256 done_event_.TimedWait(test_timeout_); 257 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_)) 262 }; 263 EXPECT_CALL(observer_, 264 AutofillEntriesChanged(ElementsAreArray(expected_changes))) 265 .WillOnce(SignalEvent(&done_event_)); 266 wds_->RemoveFormValueForElementName(name1_, value1_); 267 268 // The event will be signaled when the mock observer is notified. 269 done_event_.TimedWait(test_timeout_); 270} 271 272TEST_F(WebDataServiceAutofillTest, FormFillRemoveMany) { 273 TimeDelta one_day(TimeDelta::FromDays(1)); 274 Time t = Time::Now(); 275 276 EXPECT_CALL(observer_, AutofillEntriesChanged(_)) 277 .WillOnce(SignalEvent(&done_event_)); 278 279 std::vector<FormFieldData> form_fields; 280 AppendFormField(name1_, value1_, &form_fields); 281 AppendFormField(name2_, value2_, &form_fields); 282 wds_->AddFormFields(form_fields); 283 284 // The event will be signaled when the mock observer is notified. 285 done_event_.TimedWait(test_timeout_); 286 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_)) 292 }; 293 EXPECT_CALL(observer_, 294 AutofillEntriesChanged(ElementsAreArray(expected_changes))) 295 .WillOnce(SignalEvent(&done_event_)); 296 wds_->RemoveFormElementsAddedBetween(t, t + one_day); 297 298 // The event will be signaled when the mock observer is notified. 299 done_event_.TimedWait(test_timeout_); 300} 301 302TEST_F(WebDataServiceAutofillTest, ProfileAdd) { 303 AutofillProfile profile; 304 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_)); 310 311 wds_->AddAutofillProfile(profile); 312 done_event_.TimedWait(test_timeout_); 313 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()); 322} 323 324TEST_F(WebDataServiceAutofillTest, ProfileRemove) { 325 AutofillProfile profile; 326 327 // Add a profile. 328 EXPECT_CALL(observer_, AutofillProfileChanged(_)) 329 .WillOnce(SignalEvent(&done_event_)); 330 wds_->AddAutofillProfile(profile); 331 done_event_.TimedWait(test_timeout_); 332 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()); 341 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_)); 347 348 // Remove the profile. 349 wds_->RemoveAutofillProfile(profile.guid()); 350 done_event_.TimedWait(test_timeout_); 351 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()); 358} 359 360TEST_F(WebDataServiceAutofillTest, ProfileUpdate) { 361 AutofillProfile profile1; 362 profile1.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Abe")); 363 AutofillProfile profile2; 364 profile2.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Alice")); 365 366 EXPECT_CALL(observer_, AutofillProfileChanged(_)) 367 .WillOnce(DoDefault()) 368 .WillOnce(SignalEvent(&done_event_)); 369 370 wds_->AddAutofillProfile(profile1); 371 wds_->AddAutofillProfile(profile2); 372 done_event_.TimedWait(test_timeout_); 373 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()); 383 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); 388 389 EXPECT_CALL(observer_, AutofillProfileChanged(expected_change)) 390 .WillOnce(SignalEvent(&done_event_)); 391 392 // Update the profile. 393 wds_->UpdateAutofillProfile(profile1_changed); 394 done_event_.TimedWait(test_timeout_); 395 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()); 406} 407 408TEST_F(WebDataServiceAutofillTest, CreditAdd) { 409 CreditCard card; 410 wds_->AddCreditCard(card); 411 WaitForDatabaseThread(); 412 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()); 421} 422 423TEST_F(WebDataServiceAutofillTest, CreditCardRemove) { 424 CreditCard credit_card; 425 426 // Add a credit card. 427 wds_->AddCreditCard(credit_card); 428 WaitForDatabaseThread(); 429 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()); 438 439 // Remove the credit card. 440 wds_->RemoveCreditCard(credit_card.guid()); 441 WaitForDatabaseThread(); 442 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()); 449} 450 451TEST_F(WebDataServiceAutofillTest, CreditUpdate) { 452 CreditCard card1; 453 card1.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Abe")); 454 CreditCard card2; 455 card2.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Alice")); 456 457 wds_->AddCreditCard(card1); 458 wds_->AddCreditCard(card2); 459 WaitForDatabaseThread(); 460 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()); 470 471 CreditCard card1_changed(card1); 472 card1_changed.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Bill")); 473 474 wds_->UpdateCreditCard(card1_changed); 475 WaitForDatabaseThread(); 476 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()); 487} 488 489TEST_F(WebDataServiceAutofillTest, AutofillRemoveModifiedBetween) { 490 // Add a profile. 491 EXPECT_CALL(observer_, AutofillProfileChanged(_)) 492 .WillOnce(SignalEvent(&done_event_)); 493 AutofillProfile profile; 494 wds_->AddAutofillProfile(profile); 495 done_event_.TimedWait(test_timeout_); 496 497 // Check that it was added. 498 AutofillWebDataServiceConsumer<std::vector<AutofillProfile*> > 499 profile_consumer; 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()); 507 508 // Add a credit card. 509 CreditCard credit_card; 510 wds_->AddCreditCard(credit_card); 511 WaitForDatabaseThread(); 512 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()); 521 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_)); 527 528 // Remove the profile using time range of "all time". 529 wds_->RemoveAutofillDataModifiedBetween(Time(), Time()); 530 done_event_.TimedWait(test_timeout_); 531 WaitForDatabaseThread(); 532 533 // Check that the profile was removed. 534 AutofillWebDataServiceConsumer<std::vector<AutofillProfile*> > 535 profile_consumer2; 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()); 541 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()); 548} 549 550} // namespace autofill 551