web_data_service_unittest.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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::ASCIIToUTF16; 38using base::Time; 39using base::TimeDelta; 40using base::WaitableEvent; 41using content::BrowserThread; 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 using content::BrowserThread; 59 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 60 handle_ = handle; 61 const WDResult<T>* wrapped_result = 62 static_cast<const WDResult<T>*>(result); 63 result_ = wrapped_result->GetValue(); 64 65 base::MessageLoop::current()->Quit(); 66 } 67 68 WebDataServiceBase::Handle handle() { return handle_; } 69 T& result() { return result_; } 70 71 private: 72 WebDataServiceBase::Handle handle_; 73 T result_; 74 DISALLOW_COPY_AND_ASSIGN(AutofillWebDataServiceConsumer); 75}; 76 77} // namespace 78 79namespace autofill { 80 81static const int kWebDataServiceTimeoutSeconds = 8; 82 83ACTION_P(SignalEvent, event) { 84 event->Signal(); 85} 86 87class MockAutofillWebDataServiceObserver 88 : public AutofillWebDataServiceObserverOnDBThread { 89 public: 90 MOCK_METHOD1(AutofillEntriesChanged, 91 void(const AutofillChangeList& changes)); 92 MOCK_METHOD1(AutofillProfileChanged, 93 void(const AutofillProfileChange& change)); 94}; 95 96class WebDataServiceTest : public testing::Test { 97 public: 98 WebDataServiceTest() 99 : ui_thread_(BrowserThread::UI, &message_loop_), 100 db_thread_(BrowserThread::DB) {} 101 102 protected: 103 virtual void SetUp() { 104 db_thread_.Start(); 105 106 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 107 base::FilePath path = temp_dir_.path().AppendASCII("TestWebDB"); 108 109 wdbs_ = new WebDatabaseService( 110 path, 111 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI), 112 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB)); 113 wdbs_->AddTable(scoped_ptr<WebDatabaseTable>(new AutofillTable("en-US"))); 114 wdbs_->LoadDatabase(); 115 116 wds_ = new AutofillWebDataService( 117 wdbs_, 118 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI), 119 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB), 120 WebDataServiceBase::ProfileErrorCallback()); 121 wds_->Init(); 122 } 123 124 virtual void TearDown() { 125 wds_->ShutdownOnUIThread(); 126 wdbs_->ShutdownDatabase(); 127 wds_ = NULL; 128 wdbs_ = NULL; 129 WaitForDatabaseThread(); 130 131 base::MessageLoop::current()->PostTask(FROM_HERE, 132 base::MessageLoop::QuitClosure()); 133 base::MessageLoop::current()->Run(); 134 db_thread_.Stop(); 135 } 136 137 void WaitForDatabaseThread() { 138 base::WaitableEvent done(false, false); 139 BrowserThread::PostTask( 140 BrowserThread::DB, 141 FROM_HERE, 142 base::Bind(&base::WaitableEvent::Signal, base::Unretained(&done))); 143 done.Wait(); 144 } 145 146 base::MessageLoopForUI message_loop_; 147 content::TestBrowserThread ui_thread_; 148 content::TestBrowserThread db_thread_; 149 base::FilePath profile_dir_; 150 scoped_refptr<AutofillWebDataService> wds_; 151 scoped_refptr<WebDatabaseService> wdbs_; 152 base::ScopedTempDir temp_dir_; 153}; 154 155class WebDataServiceAutofillTest : public WebDataServiceTest { 156 public: 157 WebDataServiceAutofillTest() 158 : WebDataServiceTest(), 159 unique_id1_(1), 160 unique_id2_(2), 161 test_timeout_(TimeDelta::FromSeconds(kWebDataServiceTimeoutSeconds)), 162 done_event_(false, false) {} 163 164 protected: 165 virtual void SetUp() { 166 WebDataServiceTest::SetUp(); 167 name1_ = ASCIIToUTF16("name1"); 168 name2_ = ASCIIToUTF16("name2"); 169 value1_ = ASCIIToUTF16("value1"); 170 value2_ = ASCIIToUTF16("value2"); 171 172 void(AutofillWebDataService::*add_observer_func)( 173 AutofillWebDataServiceObserverOnDBThread*) = 174 &AutofillWebDataService::AddObserver; 175 BrowserThread::PostTask( 176 BrowserThread::DB, 177 FROM_HERE, 178 base::Bind(add_observer_func, wds_, &observer_)); 179 WaitForDatabaseThread(); 180 } 181 182 virtual void TearDown() { 183 void(AutofillWebDataService::*remove_observer_func)( 184 AutofillWebDataServiceObserverOnDBThread*) = 185 &AutofillWebDataService::RemoveObserver; 186 BrowserThread::PostTask( 187 BrowserThread::DB, 188 FROM_HERE, 189 base::Bind(remove_observer_func, wds_, &observer_)); 190 WaitForDatabaseThread(); 191 192 WebDataServiceTest::TearDown(); 193 } 194 195 void AppendFormField(const base::string16& name, 196 const base::string16& value, 197 std::vector<FormFieldData>* form_fields) { 198 FormFieldData field; 199 field.name = name; 200 field.value = value; 201 form_fields->push_back(field); 202 } 203 204 base::string16 name1_; 205 base::string16 name2_; 206 base::string16 value1_; 207 base::string16 value2_; 208 int unique_id1_, unique_id2_; 209 const TimeDelta test_timeout_; 210 testing::NiceMock<MockAutofillWebDataServiceObserver> observer_; 211 WaitableEvent done_event_; 212}; 213 214TEST_F(WebDataServiceAutofillTest, FormFillAdd) { 215 const AutofillChange expected_changes[] = { 216 AutofillChange(AutofillChange::ADD, AutofillKey(name1_, value1_)), 217 AutofillChange(AutofillChange::ADD, AutofillKey(name2_, value2_)) 218 }; 219 220 // This will verify that the correct notification is triggered, 221 // passing the correct list of autofill keys in the details. 222 EXPECT_CALL(observer_, 223 AutofillEntriesChanged(ElementsAreArray(expected_changes))) 224 .WillOnce(SignalEvent(&done_event_)); 225 226 std::vector<FormFieldData> form_fields; 227 AppendFormField(name1_, value1_, &form_fields); 228 AppendFormField(name2_, value2_, &form_fields); 229 wds_->AddFormFields(form_fields); 230 231 // The event will be signaled when the mock observer is notified. 232 done_event_.TimedWait(test_timeout_); 233 234 AutofillWebDataServiceConsumer<std::vector<base::string16> > consumer; 235 WebDataServiceBase::Handle handle; 236 static const int limit = 10; 237 handle = wds_->GetFormValuesForElementName( 238 name1_, base::string16(), limit, &consumer); 239 240 // The message loop will exit when the consumer is called. 241 base::MessageLoop::current()->Run(); 242 243 EXPECT_EQ(handle, consumer.handle()); 244 ASSERT_EQ(1U, consumer.result().size()); 245 EXPECT_EQ(value1_, consumer.result()[0]); 246} 247 248TEST_F(WebDataServiceAutofillTest, FormFillRemoveOne) { 249 // First add some values to autofill. 250 EXPECT_CALL(observer_, AutofillEntriesChanged(_)) 251 .WillOnce(SignalEvent(&done_event_)); 252 std::vector<FormFieldData> form_fields; 253 AppendFormField(name1_, value1_, &form_fields); 254 wds_->AddFormFields(form_fields); 255 256 // The event will be signaled when the mock observer is notified. 257 done_event_.TimedWait(test_timeout_); 258 259 // This will verify that the correct notification is triggered, 260 // passing the correct list of autofill keys in the details. 261 const AutofillChange expected_changes[] = { 262 AutofillChange(AutofillChange::REMOVE, AutofillKey(name1_, value1_)) 263 }; 264 EXPECT_CALL(observer_, 265 AutofillEntriesChanged(ElementsAreArray(expected_changes))) 266 .WillOnce(SignalEvent(&done_event_)); 267 wds_->RemoveFormValueForElementName(name1_, value1_); 268 269 // The event will be signaled when the mock observer is notified. 270 done_event_.TimedWait(test_timeout_); 271} 272 273TEST_F(WebDataServiceAutofillTest, FormFillRemoveMany) { 274 TimeDelta one_day(TimeDelta::FromDays(1)); 275 Time t = Time::Now(); 276 277 EXPECT_CALL(observer_, AutofillEntriesChanged(_)) 278 .WillOnce(SignalEvent(&done_event_)); 279 280 std::vector<FormFieldData> form_fields; 281 AppendFormField(name1_, value1_, &form_fields); 282 AppendFormField(name2_, value2_, &form_fields); 283 wds_->AddFormFields(form_fields); 284 285 // The event will be signaled when the mock observer is notified. 286 done_event_.TimedWait(test_timeout_); 287 288 // This will verify that the correct notification is triggered, 289 // passing the correct list of autofill keys in the details. 290 const AutofillChange expected_changes[] = { 291 AutofillChange(AutofillChange::REMOVE, AutofillKey(name1_, value1_)), 292 AutofillChange(AutofillChange::REMOVE, AutofillKey(name2_, value2_)) 293 }; 294 EXPECT_CALL(observer_, 295 AutofillEntriesChanged(ElementsAreArray(expected_changes))) 296 .WillOnce(SignalEvent(&done_event_)); 297 wds_->RemoveFormElementsAddedBetween(t, t + one_day); 298 299 // The event will be signaled when the mock observer is notified. 300 done_event_.TimedWait(test_timeout_); 301} 302 303TEST_F(WebDataServiceAutofillTest, ProfileAdd) { 304 AutofillProfile profile; 305 306 // Check that GUID-based notification was sent. 307 const AutofillProfileChange expected_change( 308 AutofillProfileChange::ADD, profile.guid(), &profile); 309 EXPECT_CALL(observer_, AutofillProfileChanged(expected_change)) 310 .WillOnce(SignalEvent(&done_event_)); 311 312 wds_->AddAutofillProfile(profile); 313 done_event_.TimedWait(test_timeout_); 314 315 // Check that it was added. 316 AutofillWebDataServiceConsumer<std::vector<AutofillProfile*> > consumer; 317 WebDataServiceBase::Handle handle = wds_->GetAutofillProfiles(&consumer); 318 base::MessageLoop::current()->Run(); 319 EXPECT_EQ(handle, consumer.handle()); 320 ASSERT_EQ(1U, consumer.result().size()); 321 EXPECT_EQ(profile, *consumer.result()[0]); 322 STLDeleteElements(&consumer.result()); 323} 324 325TEST_F(WebDataServiceAutofillTest, ProfileRemove) { 326 AutofillProfile profile; 327 328 // Add a profile. 329 EXPECT_CALL(observer_, AutofillProfileChanged(_)) 330 .WillOnce(SignalEvent(&done_event_)); 331 wds_->AddAutofillProfile(profile); 332 done_event_.TimedWait(test_timeout_); 333 334 // Check that it was added. 335 AutofillWebDataServiceConsumer<std::vector<AutofillProfile*> > consumer; 336 WebDataServiceBase::Handle handle = wds_->GetAutofillProfiles(&consumer); 337 base::MessageLoop::current()->Run(); 338 EXPECT_EQ(handle, consumer.handle()); 339 ASSERT_EQ(1U, consumer.result().size()); 340 EXPECT_EQ(profile, *consumer.result()[0]); 341 STLDeleteElements(&consumer.result()); 342 343 // Check that GUID-based notification was sent. 344 const AutofillProfileChange expected_change( 345 AutofillProfileChange::REMOVE, profile.guid(), NULL); 346 EXPECT_CALL(observer_, AutofillProfileChanged(expected_change)) 347 .WillOnce(SignalEvent(&done_event_)); 348 349 // Remove the profile. 350 wds_->RemoveAutofillProfile(profile.guid()); 351 done_event_.TimedWait(test_timeout_); 352 353 // Check that it was removed. 354 AutofillWebDataServiceConsumer<std::vector<AutofillProfile*> > consumer2; 355 WebDataServiceBase::Handle handle2 = wds_->GetAutofillProfiles(&consumer2); 356 base::MessageLoop::current()->Run(); 357 EXPECT_EQ(handle2, consumer2.handle()); 358 ASSERT_EQ(0U, consumer2.result().size()); 359} 360 361TEST_F(WebDataServiceAutofillTest, ProfileUpdate) { 362 AutofillProfile profile1; 363 profile1.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Abe")); 364 AutofillProfile profile2; 365 profile2.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Alice")); 366 367 EXPECT_CALL(observer_, AutofillProfileChanged(_)) 368 .WillOnce(DoDefault()) 369 .WillOnce(SignalEvent(&done_event_)); 370 371 wds_->AddAutofillProfile(profile1); 372 wds_->AddAutofillProfile(profile2); 373 done_event_.TimedWait(test_timeout_); 374 375 // Check that they were added. 376 AutofillWebDataServiceConsumer<std::vector<AutofillProfile*> > consumer; 377 WebDataServiceBase::Handle handle = wds_->GetAutofillProfiles(&consumer); 378 base::MessageLoop::current()->Run(); 379 EXPECT_EQ(handle, consumer.handle()); 380 ASSERT_EQ(2U, consumer.result().size()); 381 EXPECT_EQ(profile1, *consumer.result()[0]); 382 EXPECT_EQ(profile2, *consumer.result()[1]); 383 STLDeleteElements(&consumer.result()); 384 385 AutofillProfile profile1_changed(profile1); 386 profile1_changed.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Bill")); 387 const AutofillProfileChange expected_change( 388 AutofillProfileChange::UPDATE, profile1.guid(), &profile1_changed); 389 390 EXPECT_CALL(observer_, AutofillProfileChanged(expected_change)) 391 .WillOnce(SignalEvent(&done_event_)); 392 393 // Update the profile. 394 wds_->UpdateAutofillProfile(profile1_changed); 395 done_event_.TimedWait(test_timeout_); 396 397 // Check that the updates were made. 398 AutofillWebDataServiceConsumer<std::vector<AutofillProfile*> > consumer2; 399 WebDataServiceBase::Handle handle2 = wds_->GetAutofillProfiles(&consumer2); 400 base::MessageLoop::current()->Run(); 401 EXPECT_EQ(handle2, consumer2.handle()); 402 ASSERT_EQ(2U, consumer2.result().size()); 403 EXPECT_NE(profile1, *consumer2.result()[0]); 404 EXPECT_EQ(profile1_changed, *consumer2.result()[0]); 405 EXPECT_EQ(profile2, *consumer2.result()[1]); 406 STLDeleteElements(&consumer2.result()); 407} 408 409TEST_F(WebDataServiceAutofillTest, CreditAdd) { 410 CreditCard card; 411 wds_->AddCreditCard(card); 412 WaitForDatabaseThread(); 413 414 // Check that it was added. 415 AutofillWebDataServiceConsumer<std::vector<CreditCard*> > consumer; 416 WebDataServiceBase::Handle handle = wds_->GetCreditCards(&consumer); 417 base::MessageLoop::current()->Run(); 418 EXPECT_EQ(handle, consumer.handle()); 419 ASSERT_EQ(1U, consumer.result().size()); 420 EXPECT_EQ(card, *consumer.result()[0]); 421 STLDeleteElements(&consumer.result()); 422} 423 424TEST_F(WebDataServiceAutofillTest, CreditCardRemove) { 425 CreditCard credit_card; 426 427 // Add a credit card. 428 wds_->AddCreditCard(credit_card); 429 WaitForDatabaseThread(); 430 431 // Check that it was added. 432 AutofillWebDataServiceConsumer<std::vector<CreditCard*> > consumer; 433 WebDataServiceBase::Handle handle = wds_->GetCreditCards(&consumer); 434 base::MessageLoop::current()->Run(); 435 EXPECT_EQ(handle, consumer.handle()); 436 ASSERT_EQ(1U, consumer.result().size()); 437 EXPECT_EQ(credit_card, *consumer.result()[0]); 438 STLDeleteElements(&consumer.result()); 439 440 // Remove the credit card. 441 wds_->RemoveCreditCard(credit_card.guid()); 442 WaitForDatabaseThread(); 443 444 // Check that it was removed. 445 AutofillWebDataServiceConsumer<std::vector<CreditCard*> > consumer2; 446 WebDataServiceBase::Handle handle2 = wds_->GetCreditCards(&consumer2); 447 base::MessageLoop::current()->Run(); 448 EXPECT_EQ(handle2, consumer2.handle()); 449 ASSERT_EQ(0U, consumer2.result().size()); 450} 451 452TEST_F(WebDataServiceAutofillTest, CreditUpdate) { 453 CreditCard card1; 454 card1.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Abe")); 455 CreditCard card2; 456 card2.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Alice")); 457 458 wds_->AddCreditCard(card1); 459 wds_->AddCreditCard(card2); 460 WaitForDatabaseThread(); 461 462 // Check that they got added. 463 AutofillWebDataServiceConsumer<std::vector<CreditCard*> > consumer; 464 WebDataServiceBase::Handle handle = wds_->GetCreditCards(&consumer); 465 base::MessageLoop::current()->Run(); 466 EXPECT_EQ(handle, consumer.handle()); 467 ASSERT_EQ(2U, consumer.result().size()); 468 EXPECT_EQ(card1, *consumer.result()[0]); 469 EXPECT_EQ(card2, *consumer.result()[1]); 470 STLDeleteElements(&consumer.result()); 471 472 CreditCard card1_changed(card1); 473 card1_changed.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Bill")); 474 475 wds_->UpdateCreditCard(card1_changed); 476 WaitForDatabaseThread(); 477 478 // Check that the updates were made. 479 AutofillWebDataServiceConsumer<std::vector<CreditCard*> > consumer2; 480 WebDataServiceBase::Handle handle2 = wds_->GetCreditCards(&consumer2); 481 base::MessageLoop::current()->Run(); 482 EXPECT_EQ(handle2, consumer2.handle()); 483 ASSERT_EQ(2U, consumer2.result().size()); 484 EXPECT_NE(card1, *consumer2.result()[0]); 485 EXPECT_EQ(card1_changed, *consumer2.result()[0]); 486 EXPECT_EQ(card2, *consumer2.result()[1]); 487 STLDeleteElements(&consumer2.result()); 488} 489 490TEST_F(WebDataServiceAutofillTest, AutofillRemoveModifiedBetween) { 491 // Add a profile. 492 EXPECT_CALL(observer_, AutofillProfileChanged(_)) 493 .WillOnce(SignalEvent(&done_event_)); 494 AutofillProfile profile; 495 wds_->AddAutofillProfile(profile); 496 done_event_.TimedWait(test_timeout_); 497 498 // Check that it was added. 499 AutofillWebDataServiceConsumer<std::vector<AutofillProfile*> > 500 profile_consumer; 501 WebDataServiceBase::Handle handle = 502 wds_->GetAutofillProfiles(&profile_consumer); 503 base::MessageLoop::current()->Run(); 504 EXPECT_EQ(handle, profile_consumer.handle()); 505 ASSERT_EQ(1U, profile_consumer.result().size()); 506 EXPECT_EQ(profile, *profile_consumer.result()[0]); 507 STLDeleteElements(&profile_consumer.result()); 508 509 // Add a credit card. 510 CreditCard credit_card; 511 wds_->AddCreditCard(credit_card); 512 WaitForDatabaseThread(); 513 514 // Check that it was added. 515 AutofillWebDataServiceConsumer<std::vector<CreditCard*> > card_consumer; 516 handle = wds_->GetCreditCards(&card_consumer); 517 base::MessageLoop::current()->Run(); 518 EXPECT_EQ(handle, card_consumer.handle()); 519 ASSERT_EQ(1U, card_consumer.result().size()); 520 EXPECT_EQ(credit_card, *card_consumer.result()[0]); 521 STLDeleteElements(&card_consumer.result()); 522 523 // Check that GUID-based notification was sent for the profile. 524 const AutofillProfileChange expected_profile_change( 525 AutofillProfileChange::REMOVE, profile.guid(), NULL); 526 EXPECT_CALL(observer_, AutofillProfileChanged(expected_profile_change)) 527 .WillOnce(SignalEvent(&done_event_)); 528 529 // Remove the profile using time range of "all time". 530 wds_->RemoveAutofillDataModifiedBetween(Time(), Time()); 531 done_event_.TimedWait(test_timeout_); 532 WaitForDatabaseThread(); 533 534 // Check that the profile was removed. 535 AutofillWebDataServiceConsumer<std::vector<AutofillProfile*> > 536 profile_consumer2; 537 WebDataServiceBase::Handle handle2 = 538 wds_->GetAutofillProfiles(&profile_consumer2); 539 base::MessageLoop::current()->Run(); 540 EXPECT_EQ(handle2, profile_consumer2.handle()); 541 ASSERT_EQ(0U, profile_consumer2.result().size()); 542 543 // Check that the credit card was removed. 544 AutofillWebDataServiceConsumer<std::vector<CreditCard*> > card_consumer2; 545 handle2 = wds_->GetCreditCards(&card_consumer2); 546 base::MessageLoop::current()->Run(); 547 EXPECT_EQ(handle2, card_consumer2.handle()); 548 ASSERT_EQ(0U, card_consumer2.result().size()); 549} 550 551} // namespace autofill 552