web_data_service_unittest.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
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 AutofillProfile profile1; 352 profile1.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Abe")); 353 AutofillProfile profile2; 354 profile2.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Alice")); 355 356 EXPECT_CALL(observer_, AutofillProfileChanged(_)) 357 .WillOnce(DoDefault()) 358 .WillOnce(SignalEvent(&done_event_)); 359 360 wds_->AddAutofillProfile(profile1); 361 wds_->AddAutofillProfile(profile2); 362 done_event_.TimedWait(test_timeout_); 363 364 // Check that they were added. 365 AutofillWebDataServiceConsumer<std::vector<AutofillProfile*> > consumer; 366 WebDataServiceBase::Handle handle = wds_->GetAutofillProfiles(&consumer); 367 base::MessageLoop::current()->Run(); 368 EXPECT_EQ(handle, consumer.handle()); 369 ASSERT_EQ(2U, consumer.result().size()); 370 EXPECT_EQ(profile1, *consumer.result()[0]); 371 EXPECT_EQ(profile2, *consumer.result()[1]); 372 STLDeleteElements(&consumer.result()); 373 374 AutofillProfile profile1_changed(profile1); 375 profile1_changed.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Bill")); 376 const AutofillProfileChange expected_change( 377 AutofillProfileChange::UPDATE, profile1.guid(), &profile1_changed); 378 379 EXPECT_CALL(observer_, AutofillProfileChanged(expected_change)) 380 .WillOnce(SignalEvent(&done_event_)); 381 382 // Update the profile. 383 wds_->UpdateAutofillProfile(profile1_changed); 384 done_event_.TimedWait(test_timeout_); 385 386 // Check that the updates were made. 387 AutofillWebDataServiceConsumer<std::vector<AutofillProfile*> > consumer2; 388 WebDataServiceBase::Handle handle2 = wds_->GetAutofillProfiles(&consumer2); 389 base::MessageLoop::current()->Run(); 390 EXPECT_EQ(handle2, consumer2.handle()); 391 ASSERT_EQ(2U, consumer2.result().size()); 392 EXPECT_NE(profile1, *consumer2.result()[0]); 393 EXPECT_EQ(profile1_changed, *consumer2.result()[0]); 394 EXPECT_EQ(profile2, *consumer2.result()[1]); 395 STLDeleteElements(&consumer2.result()); 396} 397 398TEST_F(WebDataServiceAutofillTest, CreditAdd) { 399 CreditCard card; 400 wds_->AddCreditCard(card); 401 WaitForDatabaseThread(); 402 403 // Check that it was added. 404 AutofillWebDataServiceConsumer<std::vector<CreditCard*> > consumer; 405 WebDataServiceBase::Handle handle = wds_->GetCreditCards(&consumer); 406 base::MessageLoop::current()->Run(); 407 EXPECT_EQ(handle, consumer.handle()); 408 ASSERT_EQ(1U, consumer.result().size()); 409 EXPECT_EQ(card, *consumer.result()[0]); 410 STLDeleteElements(&consumer.result()); 411} 412 413TEST_F(WebDataServiceAutofillTest, CreditCardRemove) { 414 CreditCard credit_card; 415 416 // Add a credit card. 417 wds_->AddCreditCard(credit_card); 418 WaitForDatabaseThread(); 419 420 // Check that it was added. 421 AutofillWebDataServiceConsumer<std::vector<CreditCard*> > consumer; 422 WebDataServiceBase::Handle handle = wds_->GetCreditCards(&consumer); 423 base::MessageLoop::current()->Run(); 424 EXPECT_EQ(handle, consumer.handle()); 425 ASSERT_EQ(1U, consumer.result().size()); 426 EXPECT_EQ(credit_card, *consumer.result()[0]); 427 STLDeleteElements(&consumer.result()); 428 429 // Remove the credit card. 430 wds_->RemoveCreditCard(credit_card.guid()); 431 WaitForDatabaseThread(); 432 433 // Check that it was removed. 434 AutofillWebDataServiceConsumer<std::vector<CreditCard*> > consumer2; 435 WebDataServiceBase::Handle handle2 = wds_->GetCreditCards(&consumer2); 436 base::MessageLoop::current()->Run(); 437 EXPECT_EQ(handle2, consumer2.handle()); 438 ASSERT_EQ(0U, consumer2.result().size()); 439} 440 441TEST_F(WebDataServiceAutofillTest, CreditUpdate) { 442 CreditCard card1; 443 card1.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Abe")); 444 CreditCard card2; 445 card2.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Alice")); 446 447 wds_->AddCreditCard(card1); 448 wds_->AddCreditCard(card2); 449 WaitForDatabaseThread(); 450 451 // Check that they got added. 452 AutofillWebDataServiceConsumer<std::vector<CreditCard*> > consumer; 453 WebDataServiceBase::Handle handle = wds_->GetCreditCards(&consumer); 454 base::MessageLoop::current()->Run(); 455 EXPECT_EQ(handle, consumer.handle()); 456 ASSERT_EQ(2U, consumer.result().size()); 457 EXPECT_EQ(card1, *consumer.result()[0]); 458 EXPECT_EQ(card2, *consumer.result()[1]); 459 STLDeleteElements(&consumer.result()); 460 461 CreditCard card1_changed(card1); 462 card1_changed.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Bill")); 463 464 wds_->UpdateCreditCard(card1_changed); 465 WaitForDatabaseThread(); 466 467 // Check that the updates were made. 468 AutofillWebDataServiceConsumer<std::vector<CreditCard*> > consumer2; 469 WebDataServiceBase::Handle handle2 = wds_->GetCreditCards(&consumer2); 470 base::MessageLoop::current()->Run(); 471 EXPECT_EQ(handle2, consumer2.handle()); 472 ASSERT_EQ(2U, consumer2.result().size()); 473 EXPECT_NE(card1, *consumer2.result()[0]); 474 EXPECT_EQ(card1_changed, *consumer2.result()[0]); 475 EXPECT_EQ(card2, *consumer2.result()[1]); 476 STLDeleteElements(&consumer2.result()); 477} 478 479TEST_F(WebDataServiceAutofillTest, AutofillRemoveModifiedBetween) { 480 // Add a profile. 481 EXPECT_CALL(observer_, AutofillProfileChanged(_)) 482 .WillOnce(SignalEvent(&done_event_)); 483 AutofillProfile profile; 484 wds_->AddAutofillProfile(profile); 485 done_event_.TimedWait(test_timeout_); 486 487 // Check that it was added. 488 AutofillWebDataServiceConsumer<std::vector<AutofillProfile*> > 489 profile_consumer; 490 WebDataServiceBase::Handle handle = 491 wds_->GetAutofillProfiles(&profile_consumer); 492 base::MessageLoop::current()->Run(); 493 EXPECT_EQ(handle, profile_consumer.handle()); 494 ASSERT_EQ(1U, profile_consumer.result().size()); 495 EXPECT_EQ(profile, *profile_consumer.result()[0]); 496 STLDeleteElements(&profile_consumer.result()); 497 498 // Add a credit card. 499 CreditCard credit_card; 500 wds_->AddCreditCard(credit_card); 501 WaitForDatabaseThread(); 502 503 // Check that it was added. 504 AutofillWebDataServiceConsumer<std::vector<CreditCard*> > card_consumer; 505 handle = wds_->GetCreditCards(&card_consumer); 506 base::MessageLoop::current()->Run(); 507 EXPECT_EQ(handle, card_consumer.handle()); 508 ASSERT_EQ(1U, card_consumer.result().size()); 509 EXPECT_EQ(credit_card, *card_consumer.result()[0]); 510 STLDeleteElements(&card_consumer.result()); 511 512 // Check that GUID-based notification was sent for the profile. 513 const AutofillProfileChange expected_profile_change( 514 AutofillProfileChange::REMOVE, profile.guid(), NULL); 515 EXPECT_CALL(observer_, AutofillProfileChanged(expected_profile_change)) 516 .WillOnce(SignalEvent(&done_event_)); 517 518 // Remove the profile using time range of "all time". 519 wds_->RemoveAutofillDataModifiedBetween(Time(), Time()); 520 done_event_.TimedWait(test_timeout_); 521 WaitForDatabaseThread(); 522 523 // Check that the profile was removed. 524 AutofillWebDataServiceConsumer<std::vector<AutofillProfile*> > 525 profile_consumer2; 526 WebDataServiceBase::Handle handle2 = 527 wds_->GetAutofillProfiles(&profile_consumer2); 528 base::MessageLoop::current()->Run(); 529 EXPECT_EQ(handle2, profile_consumer2.handle()); 530 ASSERT_EQ(0U, profile_consumer2.result().size()); 531 532 // Check that the credit card was removed. 533 AutofillWebDataServiceConsumer<std::vector<CreditCard*> > card_consumer2; 534 handle2 = wds_->GetCreditCards(&card_consumer2); 535 base::MessageLoop::current()->Run(); 536 EXPECT_EQ(handle2, card_consumer2.handle()); 537 ASSERT_EQ(0U, card_consumer2.result().size()); 538} 539 540} // namespace autofill 541