• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
38 using base::ASCIIToUTF16;
39 using base::Time;
40 using base::TimeDelta;
41 using base::WaitableEvent;
42 using testing::_;
43 using testing::DoDefault;
44 using testing::ElementsAreArray;
45 using testing::Pointee;
46 using testing::Property;
47 
48 namespace {
49 
50 template <class T>
51 class AutofillWebDataServiceConsumer: public WebDataServiceConsumer {
52  public:
AutofillWebDataServiceConsumer()53   AutofillWebDataServiceConsumer() : handle_(0) {}
~AutofillWebDataServiceConsumer()54   virtual ~AutofillWebDataServiceConsumer() {}
55 
OnWebDataServiceRequestDone(WebDataServiceBase::Handle handle,const WDTypedResult * result)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 
handle()66   WebDataServiceBase::Handle handle() { return handle_; }
result()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 
77 namespace autofill {
78 
79 static const int kWebDataServiceTimeoutSeconds = 8;
80 
ACTION_P(SignalEvent,event)81 ACTION_P(SignalEvent, event) {
82   event->Signal();
83 }
84 
85 class 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 
94 class WebDataServiceTest : public testing::Test {
95  public:
WebDataServiceTest()96   WebDataServiceTest() : db_thread_("DBThread") {}
97 
98  protected:
SetUp()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 
TearDown()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 
WaitForDatabaseThread()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 
148 class WebDataServiceAutofillTest : public WebDataServiceTest {
149  public:
WebDataServiceAutofillTest()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:
SetUp()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 
TearDown()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 
AppendFormField(const base::string16 & name,const base::string16 & value,std::vector<FormFieldData> * form_fields)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 
TEST_F(WebDataServiceAutofillTest,FormFillAdd)203 TEST_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 
TEST_F(WebDataServiceAutofillTest,FormFillRemoveOne)237 TEST_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 
TEST_F(WebDataServiceAutofillTest,FormFillRemoveMany)262 TEST_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 
TEST_F(WebDataServiceAutofillTest,ProfileAdd)292 TEST_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 
TEST_F(WebDataServiceAutofillTest,ProfileRemove)314 TEST_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 
TEST_F(WebDataServiceAutofillTest,ProfileUpdate)350 TEST_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 
TEST_F(WebDataServiceAutofillTest,CreditAdd)398 TEST_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 
TEST_F(WebDataServiceAutofillTest,CreditCardRemove)413 TEST_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 
TEST_F(WebDataServiceAutofillTest,CreditUpdate)441 TEST_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 
TEST_F(WebDataServiceAutofillTest,AutofillRemoveModifiedBetween)479 TEST_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