web_data_service_unittest.cc revision 731df977c0511bca2206b5f333555b1205ff1f43
1// Copyright (c) 2010 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/file_util.h" 10#include "base/message_loop.h" 11#include "base/path_service.h" 12#include "base/ref_counted.h" 13#include "base/scoped_ptr.h" 14#include "base/scoped_vector.h" 15#include "base/stl_util-inl.h" 16#include "base/string16.h" 17#include "base/string_util.h" 18#include "base/time.h" 19#include "base/utf_string_conversions.h" 20#include "base/waitable_event.h" 21#include "chrome/browser/autofill/autofill_profile.h" 22#include "chrome/browser/autofill/credit_card.h" 23#include "chrome/browser/browser_thread.h" 24#include "chrome/browser/guid.h" 25#include "chrome/browser/webdata/autofill_change.h" 26#include "chrome/browser/webdata/autofill_entry.h" 27#include "chrome/browser/webdata/web_data_service.h" 28#include "chrome/browser/webdata/web_data_service_test_util.h" 29#include "chrome/common/chrome_paths.h" 30#include "chrome/common/notification_details.h" 31#include "chrome/common/notification_service.h" 32#include "chrome/common/notification_type.h" 33#include "chrome/test/thread_observer_helper.h" 34#include "testing/gmock/include/gmock/gmock.h" 35#include "testing/gtest/include/gtest/gtest.h" 36#include "webkit/glue/form_field.h" 37 38using base::Time; 39using base::TimeDelta; 40using base::WaitableEvent; 41using testing::_; 42using testing::DoDefault; 43using testing::ElementsAreArray; 44using testing::Pointee; 45using testing::Property; 46 47typedef std::vector<AutofillChange> AutofillChangeList; 48 49static const int kWebDataServiceTimeoutSeconds = 8; 50 51ACTION_P(SignalEvent, event) { 52 event->Signal(); 53} 54 55class AutofillDBThreadObserverHelper : public DBThreadObserverHelper { 56 protected: 57 virtual void RegisterObservers() { 58 registrar_.Add(&observer_, 59 NotificationType::AUTOFILL_ENTRIES_CHANGED, 60 NotificationService::AllSources()); 61 registrar_.Add(&observer_, 62 NotificationType::AUTOFILL_PROFILE_CHANGED, 63 NotificationService::AllSources()); 64 registrar_.Add(&observer_, 65 NotificationType::AUTOFILL_CREDIT_CARD_CHANGED, 66 NotificationService::AllSources()); 67 } 68}; 69 70class WebDataServiceTest : public testing::Test { 71 public: 72 WebDataServiceTest() 73 : ui_thread_(BrowserThread::UI, &message_loop_), 74 db_thread_(BrowserThread::DB) {} 75 76 protected: 77 virtual void SetUp() { 78 db_thread_.Start(); 79 80 PathService::Get(chrome::DIR_TEST_DATA, &profile_dir_); 81 const std::string test_profile = "WebDataServiceTest"; 82 profile_dir_ = profile_dir_.AppendASCII(test_profile); 83 file_util::Delete(profile_dir_, true); 84 file_util::CreateDirectory(profile_dir_); 85 wds_ = new WebDataService(); 86 wds_->Init(profile_dir_); 87 } 88 89 virtual void TearDown() { 90 if (wds_.get()) 91 wds_->Shutdown(); 92 file_util::Delete(profile_dir_, true); 93 94 db_thread_.Stop(); 95 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask); 96 MessageLoop::current()->Run(); 97 } 98 99 MessageLoopForUI message_loop_; 100 BrowserThread ui_thread_; 101 BrowserThread db_thread_; 102 FilePath profile_dir_; 103 scoped_refptr<WebDataService> wds_; 104}; 105 106class WebDataServiceAutofillTest : public WebDataServiceTest { 107 public: 108 WebDataServiceAutofillTest() 109 : WebDataServiceTest(), 110 unique_id1_(1), 111 unique_id2_(2), 112 test_timeout_(TimeDelta::FromSeconds(kWebDataServiceTimeoutSeconds)), 113 done_event_(false, false) {} 114 115 protected: 116 virtual void SetUp() { 117 WebDataServiceTest::SetUp(); 118 name1_ = ASCIIToUTF16("name1"); 119 name2_ = ASCIIToUTF16("name2"); 120 value1_ = ASCIIToUTF16("value1"); 121 value2_ = ASCIIToUTF16("value2"); 122 observer_helper_ = new AutofillDBThreadObserverHelper(); 123 observer_helper_->Init(); 124 } 125 126 virtual void TearDown() { 127 // Release this first so it can get destructed on the db thread. 128 observer_helper_ = NULL; 129 WebDataServiceTest::TearDown(); 130 } 131 132 void AppendFormField(const string16& name, 133 const string16& value, 134 std::vector<webkit_glue::FormField>* form_fields) { 135 form_fields->push_back( 136 webkit_glue::FormField(string16(), 137 name, 138 value, 139 string16(), 140 0)); 141 } 142 143 string16 name1_; 144 string16 name2_; 145 string16 value1_; 146 string16 value2_; 147 int unique_id1_, unique_id2_; 148 const TimeDelta test_timeout_; 149 scoped_refptr<AutofillDBThreadObserverHelper> observer_helper_; 150 WaitableEvent done_event_; 151}; 152 153TEST_F(WebDataServiceAutofillTest, FormFillAdd) { 154 const AutofillChange expected_changes[] = { 155 AutofillChange(AutofillChange::ADD, AutofillKey(name1_, value1_)), 156 AutofillChange(AutofillChange::ADD, AutofillKey(name2_, value2_)) 157 }; 158 159 // This will verify that the correct notification is triggered, 160 // passing the correct list of autofill keys in the details. 161 EXPECT_CALL( 162 *observer_helper_->observer(), 163 Observe(NotificationType(NotificationType::AUTOFILL_ENTRIES_CHANGED), 164 Source<WebDataService>(wds_.get()), 165 Property(&Details<const AutofillChangeList>::ptr, 166 Pointee(ElementsAreArray(expected_changes))))). 167 WillOnce(SignalEvent(&done_event_)); 168 169 std::vector<webkit_glue::FormField> form_fields; 170 AppendFormField(name1_, value1_, &form_fields); 171 AppendFormField(name2_, value2_, &form_fields); 172 wds_->AddFormFields(form_fields); 173 174 // The event will be signaled when the mock observer is notified. 175 done_event_.TimedWait(test_timeout_); 176 177 AutofillWebDataServiceConsumer<std::vector<string16> > consumer; 178 WebDataService::Handle handle; 179 static const int limit = 10; 180 handle = wds_->GetFormValuesForElementName( 181 name1_, string16(), limit, &consumer); 182 183 // The message loop will exit when the consumer is called. 184 MessageLoop::current()->Run(); 185 186 EXPECT_EQ(handle, consumer.handle()); 187 ASSERT_EQ(1U, consumer.result().size()); 188 EXPECT_EQ(value1_, consumer.result()[0]); 189} 190 191TEST_F(WebDataServiceAutofillTest, FormFillRemoveOne) { 192 // First add some values to autofill. 193 EXPECT_CALL(*observer_helper_->observer(), Observe(_, _, _)). 194 WillOnce(SignalEvent(&done_event_)); 195 std::vector<webkit_glue::FormField> form_fields; 196 AppendFormField(name1_, value1_, &form_fields); 197 wds_->AddFormFields(form_fields); 198 199 // The event will be signaled when the mock observer is notified. 200 done_event_.TimedWait(test_timeout_); 201 202 // This will verify that the correct notification is triggered, 203 // passing the correct list of autofill keys in the details. 204 const AutofillChange expected_changes[] = { 205 AutofillChange(AutofillChange::REMOVE, AutofillKey(name1_, value1_)) 206 }; 207 EXPECT_CALL( 208 *observer_helper_->observer(), 209 Observe(NotificationType(NotificationType::AUTOFILL_ENTRIES_CHANGED), 210 Source<WebDataService>(wds_.get()), 211 Property(&Details<const AutofillChangeList>::ptr, 212 Pointee(ElementsAreArray(expected_changes))))). 213 WillOnce(SignalEvent(&done_event_)); 214 wds_->RemoveFormValueForElementName(name1_, value1_); 215 216 // The event will be signaled when the mock observer is notified. 217 done_event_.TimedWait(test_timeout_); 218} 219 220TEST_F(WebDataServiceAutofillTest, FormFillRemoveMany) { 221 TimeDelta one_day(TimeDelta::FromDays(1)); 222 Time t = Time::Now(); 223 224 EXPECT_CALL(*observer_helper_->observer(), Observe(_, _, _)). 225 WillOnce(SignalEvent(&done_event_)); 226 std::vector<webkit_glue::FormField> 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 // This will verify that the correct notification is triggered, 235 // passing the correct list of autofill keys in the details. 236 const AutofillChange expected_changes[] = { 237 AutofillChange(AutofillChange::REMOVE, AutofillKey(name1_, value1_)), 238 AutofillChange(AutofillChange::REMOVE, AutofillKey(name2_, value2_)) 239 }; 240 EXPECT_CALL( 241 *observer_helper_->observer(), 242 Observe(NotificationType(NotificationType::AUTOFILL_ENTRIES_CHANGED), 243 Source<WebDataService>(wds_.get()), 244 Property(&Details<const AutofillChangeList>::ptr, 245 Pointee(ElementsAreArray(expected_changes))))). 246 WillOnce(SignalEvent(&done_event_)); 247 wds_->RemoveFormElementsAddedBetween(t, t + one_day); 248 249 // The event will be signaled when the mock observer is notified. 250 done_event_.TimedWait(test_timeout_); 251} 252 253TEST_F(WebDataServiceAutofillTest, ProfileAdd) { 254 AutoFillProfile profile(name1_, unique_id1_); 255 const AutofillProfileChange expected_change( 256 AutofillProfileChange::ADD, name1_, &profile, string16()); 257 258 EXPECT_CALL( 259 *observer_helper_->observer(), 260 Observe(NotificationType(NotificationType::AUTOFILL_PROFILE_CHANGED), 261 Source<WebDataService>(wds_.get()), 262 Property(&Details<const AutofillProfileChange>::ptr, 263 Pointee(expected_change)))). 264 WillOnce(SignalEvent(&done_event_)); 265 266 wds_->AddAutoFillProfile(profile); 267 done_event_.TimedWait(test_timeout_); 268} 269 270TEST_F(WebDataServiceAutofillTest, ProfileRemove) { 271 AutoFillProfile profile(name1_, unique_id1_); 272 273 EXPECT_CALL(*observer_helper_->observer(), Observe(_, _, _)). 274 WillOnce(SignalEvent(&done_event_)); 275 wds_->AddAutoFillProfile(profile); 276 done_event_.TimedWait(test_timeout_); 277 278 const AutofillProfileChange expected_change( 279 AutofillProfileChange::REMOVE, name1_, NULL, string16()); 280 EXPECT_CALL( 281 *observer_helper_->observer(), 282 Observe(NotificationType(NotificationType::AUTOFILL_PROFILE_CHANGED), 283 Source<WebDataService>(wds_.get()), 284 Property(&Details<const AutofillProfileChange>::ptr, 285 Pointee(expected_change)))). 286 WillOnce(SignalEvent(&done_event_)); 287 288 wds_->RemoveAutoFillProfile(profile.unique_id()); 289 done_event_.TimedWait(test_timeout_); 290} 291 292TEST_F(WebDataServiceAutofillTest, ProfileRemoveGUID) { 293 AutoFillProfile profile(name1_, unique_id1_); 294 295 // Add a profile. 296 EXPECT_CALL(*observer_helper_->observer(), Observe(_, _, _)). 297 WillOnce(SignalEvent(&done_event_)); 298 wds_->AddAutoFillProfile(profile); 299 done_event_.TimedWait(test_timeout_); 300 301 // Check that it was added. 302 AutofillWebDataServiceConsumer<std::vector<AutoFillProfile*> > consumer; 303 WebDataService::Handle handle = wds_->GetAutoFillProfiles(&consumer); 304 MessageLoop::current()->Run(); 305 EXPECT_EQ(handle, consumer.handle()); 306 ASSERT_EQ(1U, consumer.result().size()); 307 EXPECT_EQ(profile, *consumer.result()[0]); 308 STLDeleteElements(&consumer.result()); 309 310 // Remove the profile. 311 const AutofillProfileChange expected_change( 312 AutofillProfileChange::REMOVE, name1_, NULL, string16()); 313 EXPECT_CALL( 314 *observer_helper_->observer(), 315 Observe(NotificationType(NotificationType::AUTOFILL_PROFILE_CHANGED), 316 Source<WebDataService>(wds_.get()), 317 Property(&Details<const AutofillProfileChange>::ptr, 318 Pointee(expected_change)))). 319 WillOnce(SignalEvent(&done_event_)); 320 wds_->RemoveAutoFillProfile(profile.guid()); 321 done_event_.TimedWait(test_timeout_); 322 323 // Check that it was removed. 324 AutofillWebDataServiceConsumer<std::vector<AutoFillProfile*> > consumer2; 325 WebDataService::Handle handle2 = wds_->GetAutoFillProfiles(&consumer2); 326 MessageLoop::current()->Run(); 327 EXPECT_EQ(handle2, consumer2.handle()); 328 ASSERT_EQ(0U, consumer2.result().size()); 329} 330 331TEST_F(WebDataServiceAutofillTest, ProfileUpdate) { 332 AutoFillProfile profile1(name1_, unique_id1_); 333 AutoFillProfile profile2(name2_, unique_id2_); 334 335 EXPECT_CALL(*observer_helper_->observer(), Observe(_, _, _)). 336 Times(2). 337 WillOnce(DoDefault()). 338 WillOnce(SignalEvent(&done_event_)); 339 wds_->AddAutoFillProfile(profile1); 340 wds_->AddAutoFillProfile(profile2); 341 342 done_event_.TimedWait(test_timeout_); 343 344 AutoFillProfile profile1_delta(profile1); 345 string16 new_label(ASCIIToUTF16("new_label!")); 346 profile1_delta.set_label(new_label); 347 const AutofillProfileChange expected_change( 348 AutofillProfileChange::UPDATE, new_label, &profile1_delta, name1_); 349 350 EXPECT_CALL( 351 *observer_helper_->observer(), 352 Observe(NotificationType(NotificationType::AUTOFILL_PROFILE_CHANGED), 353 Source<WebDataService>(wds_.get()), 354 Property(&Details<const AutofillProfileChange>::ptr, 355 Pointee(expected_change)))). 356 WillOnce(SignalEvent(&done_event_)); 357 358 wds_->UpdateAutoFillProfile(profile1_delta); 359 done_event_.TimedWait(test_timeout_); 360} 361 362TEST_F(WebDataServiceAutofillTest, CreditAdd) { 363 CreditCard card(name1_, unique_id1_); 364 const AutofillCreditCardChange expected_change( 365 AutofillCreditCardChange::ADD, name1_, &card); 366 367 EXPECT_CALL( 368 *observer_helper_->observer(), 369 Observe(NotificationType(NotificationType::AUTOFILL_CREDIT_CARD_CHANGED), 370 Source<WebDataService>(wds_.get()), 371 Property(&Details<const AutofillCreditCardChange>::ptr, 372 Pointee(expected_change)))). 373 WillOnce(SignalEvent(&done_event_)); 374 375 wds_->AddCreditCard(card); 376 done_event_.TimedWait(test_timeout_); 377} 378 379TEST_F(WebDataServiceAutofillTest, CreditRemove) { 380 CreditCard card(name1_, unique_id1_); 381 EXPECT_CALL(*observer_helper_->observer(), Observe(_, _, _)). 382 WillOnce(SignalEvent(&done_event_)); 383 wds_->AddCreditCard(card); 384 done_event_.TimedWait(test_timeout_); 385 386 const AutofillCreditCardChange expected_change( 387 AutofillCreditCardChange::REMOVE, name1_, NULL); 388 389 EXPECT_CALL( 390 *observer_helper_->observer(), 391 Observe(NotificationType(NotificationType::AUTOFILL_CREDIT_CARD_CHANGED), 392 Source<WebDataService>(wds_.get()), 393 Property(&Details<const AutofillCreditCardChange>::ptr, 394 Pointee(expected_change)))). 395 WillOnce(SignalEvent(&done_event_)); 396 397 wds_->RemoveCreditCard(card.unique_id()); 398 done_event_.TimedWait(test_timeout_); 399} 400 401TEST_F(WebDataServiceAutofillTest, CreditCardRemoveGUID) { 402 CreditCard card(name1_, unique_id1_); 403 404 // Add a credit card. 405 EXPECT_CALL(*observer_helper_->observer(), Observe(_, _, _)). 406 WillOnce(SignalEvent(&done_event_)); 407 wds_->AddCreditCard(card); 408 done_event_.TimedWait(test_timeout_); 409 410 // Check that it was added. 411 AutofillWebDataServiceConsumer<std::vector<CreditCard*> > consumer; 412 WebDataService::Handle handle = wds_->GetCreditCards(&consumer); 413 MessageLoop::current()->Run(); 414 EXPECT_EQ(handle, consumer.handle()); 415 ASSERT_EQ(1U, consumer.result().size()); 416 EXPECT_EQ(card, *consumer.result()[0]); 417 STLDeleteElements(&consumer.result()); 418 419 // Remove the credit card. 420 const AutofillCreditCardChange expected_change( 421 AutofillCreditCardChange::REMOVE, name1_, NULL); 422 EXPECT_CALL( 423 *observer_helper_->observer(), 424 Observe(NotificationType(NotificationType::AUTOFILL_CREDIT_CARD_CHANGED), 425 Source<WebDataService>(wds_.get()), 426 Property(&Details<const AutofillCreditCardChange>::ptr, 427 Pointee(expected_change)))). 428 WillOnce(SignalEvent(&done_event_)); 429 wds_->RemoveCreditCard(card.guid()); 430 done_event_.TimedWait(test_timeout_); 431 432 // Check that it was removed. 433 AutofillWebDataServiceConsumer<std::vector<CreditCard*> > consumer2; 434 WebDataService::Handle handle2 = wds_->GetCreditCards(&consumer2); 435 MessageLoop::current()->Run(); 436 EXPECT_EQ(handle2, consumer2.handle()); 437 ASSERT_EQ(0U, consumer2.result().size()); 438} 439 440TEST_F(WebDataServiceAutofillTest, CreditUpdate) { 441 CreditCard card1(name1_, unique_id1_); 442 CreditCard card2(name2_, unique_id2_); 443 444 EXPECT_CALL(*observer_helper_->observer(), Observe(_, _, _)). 445 Times(2). 446 WillOnce(DoDefault()). 447 WillOnce(SignalEvent(&done_event_)); 448 wds_->AddCreditCard(card1); 449 wds_->AddCreditCard(card2); 450 done_event_.TimedWait(test_timeout_); 451 452 CreditCard card1_delta(card1); 453 card1_delta.set_label(ASCIIToUTF16("new_label!")); 454 const AutofillCreditCardChange expected_change( 455 AutofillCreditCardChange::UPDATE, name1_, &card1_delta); 456 457 EXPECT_CALL( 458 *observer_helper_->observer(), 459 Observe(NotificationType(NotificationType::AUTOFILL_CREDIT_CARD_CHANGED), 460 Source<WebDataService>(wds_.get()), 461 Property(&Details<const AutofillCreditCardChange>::ptr, 462 Pointee(expected_change)))). 463 WillOnce(SignalEvent(&done_event_)); 464 465 wds_->UpdateCreditCard(card1_delta); 466 done_event_.TimedWait(test_timeout_); 467} 468