Home | History | Annotate | Download | only in integration
      1 // Copyright (c) 2012 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 "chrome/browser/sync/test/integration/autofill_helper.h"
      6 
      7 #include "chrome/browser/autofill/personal_data_manager_factory.h"
      8 #include "chrome/browser/chrome_notification_types.h"
      9 #include "chrome/browser/profiles/profile.h"
     10 #include "chrome/browser/sync/profile_sync_service.h"
     11 #include "chrome/browser/sync/profile_sync_test_util.h"
     12 #include "chrome/browser/sync/test/integration/sync_datatype_helper.h"
     13 #include "chrome/browser/sync/test/integration/sync_test.h"
     14 #include "chrome/browser/webdata/web_data_service_factory.h"
     15 #include "components/autofill/core/browser/autofill_profile.h"
     16 #include "components/autofill/core/browser/autofill_test_utils.h"
     17 #include "components/autofill/core/browser/autofill_type.h"
     18 #include "components/autofill/core/browser/personal_data_manager.h"
     19 #include "components/autofill/core/browser/personal_data_manager_observer.h"
     20 #include "components/autofill/core/browser/webdata/autofill_entry.h"
     21 #include "components/autofill/core/browser/webdata/autofill_table.h"
     22 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
     23 #include "components/autofill/core/common/form_field_data.h"
     24 #include "components/webdata/common/web_database.h"
     25 
     26 using autofill::AutofillChangeList;
     27 using autofill::AutofillEntry;
     28 using autofill::AutofillKey;
     29 using autofill::AutofillProfile;
     30 using autofill::AutofillTable;
     31 using autofill::AutofillType;
     32 using autofill::AutofillWebDataService;
     33 using autofill::AutofillWebDataServiceObserverOnDBThread;
     34 using autofill::CreditCard;
     35 using autofill::FormFieldData;
     36 using autofill::PersonalDataManager;
     37 using autofill::PersonalDataManagerObserver;
     38 using base::WaitableEvent;
     39 using content::BrowserThread;
     40 using sync_datatype_helper::test;
     41 using testing::_;
     42 
     43 namespace {
     44 
     45 ACTION_P(SignalEvent, event) {
     46   event->Signal();
     47 }
     48 
     49 class MockWebDataServiceObserver
     50     : public AutofillWebDataServiceObserverOnDBThread {
     51  public:
     52   MOCK_METHOD1(AutofillEntriesChanged,
     53                void(const AutofillChangeList& changes));
     54 };
     55 
     56 class MockPersonalDataManagerObserver : public PersonalDataManagerObserver {
     57  public:
     58   MOCK_METHOD0(OnPersonalDataChanged, void());
     59 };
     60 
     61 void RunOnDBThreadAndSignal(base::Closure task,
     62                             base::WaitableEvent* done_event) {
     63   if (!task.is_null()) {
     64     task.Run();
     65   }
     66   done_event->Signal();
     67 }
     68 
     69 void RunOnDBThreadAndBlock(base::Closure task) {
     70   WaitableEvent done_event(false, false);
     71   BrowserThread::PostTask(BrowserThread::DB,
     72                           FROM_HERE,
     73                           Bind(&RunOnDBThreadAndSignal, task, &done_event));
     74   done_event.Wait();
     75 }
     76 
     77 void RemoveKeyDontBlockForSync(int profile, const AutofillKey& key) {
     78   WaitableEvent done_event(false, false);
     79 
     80   MockWebDataServiceObserver mock_observer;
     81   EXPECT_CALL(mock_observer, AutofillEntriesChanged(_))
     82       .WillOnce(SignalEvent(&done_event));
     83 
     84   scoped_refptr<AutofillWebDataService> wds =
     85       autofill_helper::GetWebDataService(profile);
     86 
     87   void(AutofillWebDataService::*add_observer_func)(
     88       AutofillWebDataServiceObserverOnDBThread*) =
     89       &AutofillWebDataService::AddObserver;
     90   RunOnDBThreadAndBlock(Bind(add_observer_func, wds, &mock_observer));
     91 
     92   wds->RemoveFormValueForElementName(key.name(), key.value());
     93   done_event.Wait();
     94 
     95   void(AutofillWebDataService::*remove_observer_func)(
     96       AutofillWebDataServiceObserverOnDBThread*) =
     97       &AutofillWebDataService::RemoveObserver;
     98   RunOnDBThreadAndBlock(Bind(remove_observer_func, wds, &mock_observer));
     99 }
    100 
    101 void GetAllAutofillEntriesOnDBThread(AutofillWebDataService* wds,
    102                                      std::vector<AutofillEntry>* entries) {
    103   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
    104   AutofillTable::FromWebDatabase(
    105       wds->GetDatabase())->GetAllAutofillEntries(entries);
    106 }
    107 
    108 std::vector<AutofillEntry> GetAllAutofillEntries(AutofillWebDataService* wds) {
    109   std::vector<AutofillEntry> entries;
    110   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    111   RunOnDBThreadAndBlock(Bind(&GetAllAutofillEntriesOnDBThread,
    112                              Unretained(wds),
    113                              &entries));
    114   return entries;
    115 }
    116 
    117 // UI thread returns from the update operations on the DB thread and schedules
    118 // the sync. This function blocks until after this scheduled sync is complete by
    119 // scheduling additional empty task on DB Thread. Call after AddKeys/RemoveKey.
    120 void BlockForPendingDBThreadTasks() {
    121   // The order of the notifications is undefined, so sync change sometimes is
    122   // posted after the notification for observer_helper. Post new task to db
    123   // thread that guaranteed to be after sync and would be blocking until
    124   // completion.
    125   RunOnDBThreadAndBlock(base::Closure());
    126 }
    127 
    128 }  // namespace
    129 
    130 namespace autofill_helper {
    131 
    132 AutofillProfile CreateAutofillProfile(ProfileType type) {
    133   AutofillProfile profile;
    134   switch (type) {
    135     case PROFILE_MARION:
    136       autofill::test::SetProfileInfoWithGuid(&profile,
    137           "C837507A-6C3B-4872-AC14-5113F157D668",
    138           "Marion", "Mitchell", "Morrison",
    139           "johnwayne (at) me.xyz", "Fox",
    140           "123 Zoo St.", "unit 5", "Hollywood", "CA",
    141           "91601", "US", "12345678910");
    142       break;
    143     case PROFILE_HOMER:
    144       autofill::test::SetProfileInfoWithGuid(&profile,
    145           "137DE1C3-6A30-4571-AC86-109B1ECFBE7F",
    146           "Homer", "J.", "Simpson",
    147           "homer (at) abc.com", "SNPP",
    148           "1 Main St", "PO Box 1", "Springfield", "MA",
    149           "94101", "US", "14155551212");
    150       break;
    151     case PROFILE_FRASIER:
    152       autofill::test::SetProfileInfoWithGuid(&profile,
    153           "9A5E6872-6198-4688-BF75-0016E781BB0A",
    154           "Frasier", "Winslow", "Crane",
    155           "", "randomness", "", "Apt. 4", "Seattle", "WA",
    156           "99121", "US", "0000000000");
    157       break;
    158     case PROFILE_NULL:
    159       autofill::test::SetProfileInfoWithGuid(&profile,
    160           "FE461507-7E13-4198-8E66-74C7DB6D8322",
    161           "", "", "", "", "", "", "", "", "", "", "", "");
    162       break;
    163   }
    164   return profile;
    165 }
    166 
    167 scoped_refptr<AutofillWebDataService> GetWebDataService(int index) {
    168   return WebDataServiceFactory::GetAutofillWebDataForProfile(
    169       test()->GetProfile(index), Profile::EXPLICIT_ACCESS);
    170 }
    171 
    172 PersonalDataManager* GetPersonalDataManager(int index) {
    173   return autofill::PersonalDataManagerFactory::GetForProfile(
    174       test()->GetProfile(index));
    175 }
    176 
    177 void AddKeys(int profile, const std::set<AutofillKey>& keys) {
    178   std::vector<FormFieldData> form_fields;
    179   for (std::set<AutofillKey>::const_iterator i = keys.begin();
    180        i != keys.end();
    181        ++i) {
    182     FormFieldData field;
    183     field.name = i->name();
    184     field.value = i->value();
    185     form_fields.push_back(field);
    186   }
    187 
    188   WaitableEvent done_event(false, false);
    189   MockWebDataServiceObserver mock_observer;
    190   EXPECT_CALL(mock_observer, AutofillEntriesChanged(_))
    191       .WillOnce(SignalEvent(&done_event));
    192 
    193   scoped_refptr<AutofillWebDataService> wds = GetWebDataService(profile);
    194 
    195   void(AutofillWebDataService::*add_observer_func)(
    196       AutofillWebDataServiceObserverOnDBThread*) =
    197       &AutofillWebDataService::AddObserver;
    198   RunOnDBThreadAndBlock(Bind(add_observer_func, wds, &mock_observer));
    199 
    200   wds->AddFormFields(form_fields);
    201   done_event.Wait();
    202   BlockForPendingDBThreadTasks();
    203 
    204   void(AutofillWebDataService::*remove_observer_func)(
    205       AutofillWebDataServiceObserverOnDBThread*) =
    206       &AutofillWebDataService::RemoveObserver;
    207   RunOnDBThreadAndBlock(Bind(remove_observer_func, wds, &mock_observer));
    208 }
    209 
    210 void RemoveKey(int profile, const AutofillKey& key) {
    211   RemoveKeyDontBlockForSync(profile, key);
    212   BlockForPendingDBThreadTasks();
    213 }
    214 
    215 void RemoveKeys(int profile) {
    216   std::set<AutofillEntry> keys = GetAllKeys(profile);
    217   for (std::set<AutofillEntry>::const_iterator it = keys.begin();
    218        it != keys.end(); ++it) {
    219     RemoveKeyDontBlockForSync(profile, it->key());
    220   }
    221   BlockForPendingDBThreadTasks();
    222 }
    223 
    224 std::set<AutofillEntry> GetAllKeys(int profile) {
    225   scoped_refptr<AutofillWebDataService> wds = GetWebDataService(profile);
    226   std::vector<AutofillEntry> all_entries = GetAllAutofillEntries(wds.get());
    227   std::set<AutofillEntry> all_keys;
    228   for (std::vector<AutofillEntry>::const_iterator it = all_entries.begin();
    229        it != all_entries.end(); ++it) {
    230     all_keys.insert(*it);
    231   }
    232   return all_keys;
    233 }
    234 
    235 bool KeysMatch(int profile_a, int profile_b) {
    236   return GetAllKeys(profile_a) == GetAllKeys(profile_b);
    237 }
    238 
    239 void SetProfiles(int profile, std::vector<AutofillProfile>* autofill_profiles) {
    240   MockPersonalDataManagerObserver observer;
    241   EXPECT_CALL(observer, OnPersonalDataChanged()).
    242       WillOnce(QuitUIMessageLoop());
    243   PersonalDataManager* pdm = GetPersonalDataManager(profile);
    244   pdm->AddObserver(&observer);
    245   pdm->SetProfiles(autofill_profiles);
    246   base::MessageLoop::current()->Run();
    247   pdm->RemoveObserver(&observer);
    248 }
    249 
    250 void SetCreditCards(int profile, std::vector<CreditCard>* credit_cards) {
    251   MockPersonalDataManagerObserver observer;
    252   EXPECT_CALL(observer, OnPersonalDataChanged()).
    253       WillOnce(QuitUIMessageLoop());
    254   PersonalDataManager* pdm = GetPersonalDataManager(profile);
    255   pdm->AddObserver(&observer);
    256   pdm->SetCreditCards(credit_cards);
    257   base::MessageLoop::current()->Run();
    258   pdm->RemoveObserver(&observer);
    259 }
    260 
    261 void AddProfile(int profile, const AutofillProfile& autofill_profile) {
    262   const std::vector<AutofillProfile*>& all_profiles = GetAllProfiles(profile);
    263   std::vector<AutofillProfile> autofill_profiles;
    264   for (size_t i = 0; i < all_profiles.size(); ++i)
    265     autofill_profiles.push_back(*all_profiles[i]);
    266   autofill_profiles.push_back(autofill_profile);
    267   autofill_helper::SetProfiles(profile, &autofill_profiles);
    268 }
    269 
    270 void RemoveProfile(int profile, const std::string& guid) {
    271   const std::vector<AutofillProfile*>& all_profiles = GetAllProfiles(profile);
    272   std::vector<AutofillProfile> autofill_profiles;
    273   for (size_t i = 0; i < all_profiles.size(); ++i) {
    274     if (all_profiles[i]->guid() != guid)
    275       autofill_profiles.push_back(*all_profiles[i]);
    276   }
    277   autofill_helper::SetProfiles(profile, &autofill_profiles);
    278 }
    279 
    280 void UpdateProfile(int profile,
    281                    const std::string& guid,
    282                    const AutofillType& type,
    283                    const base::string16& value) {
    284   const std::vector<AutofillProfile*>& all_profiles = GetAllProfiles(profile);
    285   std::vector<AutofillProfile> profiles;
    286   for (size_t i = 0; i < all_profiles.size(); ++i) {
    287     profiles.push_back(*all_profiles[i]);
    288     if (all_profiles[i]->guid() == guid)
    289       profiles.back().SetRawInfo(type.GetStorableType(), value);
    290   }
    291   autofill_helper::SetProfiles(profile, &profiles);
    292 }
    293 
    294 const std::vector<AutofillProfile*>& GetAllProfiles(
    295     int profile) {
    296   MockPersonalDataManagerObserver observer;
    297   EXPECT_CALL(observer, OnPersonalDataChanged()).
    298       WillOnce(QuitUIMessageLoop());
    299   PersonalDataManager* pdm = GetPersonalDataManager(profile);
    300   pdm->AddObserver(&observer);
    301   pdm->Refresh();
    302   base::MessageLoop::current()->Run();
    303   pdm->RemoveObserver(&observer);
    304   return pdm->web_profiles();
    305 }
    306 
    307 int GetProfileCount(int profile) {
    308   return GetAllProfiles(profile).size();
    309 }
    310 
    311 int GetKeyCount(int profile) {
    312   return GetAllKeys(profile).size();
    313 }
    314 
    315 bool ProfilesMatch(int profile_a, int profile_b) {
    316   const std::vector<AutofillProfile*>& autofill_profiles_a =
    317       GetAllProfiles(profile_a);
    318   std::map<std::string, AutofillProfile> autofill_profiles_a_map;
    319   for (size_t i = 0; i < autofill_profiles_a.size(); ++i) {
    320     const AutofillProfile* p = autofill_profiles_a[i];
    321     autofill_profiles_a_map[p->guid()] = *p;
    322   }
    323 
    324   const std::vector<AutofillProfile*>& autofill_profiles_b =
    325       GetAllProfiles(profile_b);
    326   for (size_t i = 0; i < autofill_profiles_b.size(); ++i) {
    327     const AutofillProfile* p = autofill_profiles_b[i];
    328     if (!autofill_profiles_a_map.count(p->guid())) {
    329       LOG(ERROR) << "GUID " << p->guid() << " not found in profile "
    330                  << profile_b << ".";
    331       return false;
    332     }
    333     AutofillProfile* expected_profile = &autofill_profiles_a_map[p->guid()];
    334     expected_profile->set_guid(p->guid());
    335     if (*expected_profile != *p) {
    336       LOG(ERROR) << "Mismatch in profile with GUID " << p->guid() << ".";
    337       return false;
    338     }
    339     autofill_profiles_a_map.erase(p->guid());
    340   }
    341 
    342   if (autofill_profiles_a_map.size()) {
    343     LOG(ERROR) << "Entries present in Profile " << profile_a
    344                << " but not in " << profile_b << ".";
    345     return false;
    346   }
    347   return true;
    348 }
    349 
    350 bool AllProfilesMatch() {
    351   for (int i = 1; i < test()->num_clients(); ++i) {
    352     if (!ProfilesMatch(0, i)) {
    353       LOG(ERROR) << "Profile " << i << "does not contain the same autofill "
    354                                        "profiles as profile 0.";
    355       return false;
    356     }
    357   }
    358   return true;
    359 }
    360 
    361 }  // namespace autofill_helper
    362