- add sources.
[platform/framework/web/crosswalk.git] / src / components / autofill / core / browser / webdata / web_data_service_unittest.cc
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
37 using base::Time;
38 using base::TimeDelta;
39 using base::WaitableEvent;
40 using content::BrowserThread;
41 using testing::_;
42 using testing::DoDefault;
43 using testing::ElementsAreArray;
44 using testing::Pointee;
45 using testing::Property;
46
47 namespace {
48
49 template <class T>
50 class 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
78 namespace autofill {
79
80 static const int kWebDataServiceTimeoutSeconds = 8;
81
82 ACTION_P(SignalEvent, event) {
83   event->Signal();
84 }
85
86 class 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
95 class 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
154 class 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
213 TEST_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
247 TEST_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
272 TEST_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
302 TEST_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
324 TEST_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
360 TEST_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
408 TEST_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
423 TEST_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
451 TEST_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
489 TEST_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