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