Home | History | Annotate | Download | only in glue
      1 // Copyright (c) 2011 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 "base/utf_string_conversions.h"
      6 #include "chrome/browser/sync/engine/read_node_mock.h"
      7 #include "chrome/browser/sync/engine/syncapi_mock.h"
      8 #include "chrome/browser/sync/glue/autofill_profile_model_associator.h"
      9 #include "chrome/browser/sync/syncable/syncable.h"
     10 #include "chrome/browser/sync/syncable/syncable_mock.h"
     11 #include "testing/gmock/include/gmock/gmock.h"
     12 #include "testing/gtest/include/gtest/gtest.h"
     13 
     14 using ::testing::_;
     15 using ::testing::Return;
     16 using ::testing::DoDefault;
     17 using ::testing::ReturnRef;
     18 using ::testing::Pointee;
     19 using ::testing::Ref;
     20 using ::testing::Invoke;
     21 class AutofillProfile;
     22 
     23 using browser_sync::AutofillProfileModelAssociator;
     24 
     25 // Note this is not a generic mock. This is a mock used to
     26 // test AutofillProfileModelAssociator class itself by mocking
     27 // other functions that are called by the functions we need to test.
     28 class MockAutofillProfileModelAssociator
     29     : public AutofillProfileModelAssociator {
     30  public:
     31   MockAutofillProfileModelAssociator() {
     32   }
     33   virtual ~MockAutofillProfileModelAssociator() {}
     34   bool TraverseAndAssociateChromeAutofillProfilesWrapper(
     35       sync_api::WriteTransaction* write_trans,
     36       const sync_api::ReadNode& autofill_root,
     37       const std::vector<AutofillProfile*>& all_profiles_from_db,
     38       std::set<std::string>* current_profiles,
     39       std::vector<AutofillProfile*>* updated_profiles,
     40       std::vector<AutofillProfile*>* new_profiles,
     41       std::vector<std::string>* profiles_to_delete) {
     42       return TraverseAndAssociateChromeAutofillProfiles(write_trans,
     43           autofill_root,
     44           all_profiles_from_db,
     45           current_profiles,
     46           updated_profiles,
     47           new_profiles,
     48           profiles_to_delete);
     49   }
     50   MOCK_METHOD3(AddNativeProfileIfNeeded,
     51                void(const sync_pb::AutofillProfileSpecifics&,
     52                     DataBundle*,
     53                     const sync_api::ReadNode&));
     54   MOCK_METHOD2(OverwriteProfileWithServerData,
     55                bool(AutofillProfile*,
     56                     const sync_pb::AutofillProfileSpecifics&));
     57   MOCK_METHOD6(MakeNewAutofillProfileSyncNodeIfNeeded,
     58                bool(sync_api::WriteTransaction*,
     59                     const sync_api::BaseNode&,
     60                     const AutofillProfile&,
     61                     std::vector<AutofillProfile*>*,
     62                     std::set<std::string>*,
     63                     std::vector<std::string>*));
     64   MOCK_METHOD2(Associate, void(const std::string*, int64));
     65 
     66   bool TraverseAndAssociateAllSyncNodesWrapper(
     67       sync_api::WriteTransaction *trans,
     68       const sync_api::ReadNode &autofill_root,
     69       browser_sync::AutofillProfileModelAssociator::DataBundle *bundle) {
     70       return TraverseAndAssociateAllSyncNodes(trans, autofill_root, bundle);
     71   }
     72 
     73   void AddNativeProfileIfNeededWrapper(
     74       const sync_pb::AutofillProfileSpecifics& profile,
     75       DataBundle* bundle,
     76       const sync_api::ReadNode& node) {
     77     AutofillProfileModelAssociator::AddNativeProfileIfNeeded(
     78         profile,
     79         bundle,
     80         node);
     81   }
     82 };
     83 
     84 class AutofillProfileModelAssociatorTest : public testing::Test {
     85  public:
     86   AutofillProfileModelAssociatorTest()
     87     : db_thread_(BrowserThread::DB, &message_loop_) {}
     88 
     89  protected:
     90   MessageLoop message_loop_;
     91   BrowserThread db_thread_;
     92   MockAutofillProfileModelAssociator associator_;
     93 };
     94 
     95 TEST_F(AutofillProfileModelAssociatorTest,
     96     TestAssociateProfileInWebDBWithSyncDB) {
     97   ScopedVector<AutofillProfile> profiles_from_web_db;
     98   std::string guid = "EDC609ED-7EEE-4F27-B00C-423242A9C44B";
     99 
    100   sync_pb::EntitySpecifics specifics;
    101   MockDirectory mock_directory;
    102   sync_pb::AutofillProfileSpecifics *profile_specifics =
    103     specifics.MutableExtension(sync_pb::autofill_profile);
    104 
    105   profile_specifics->set_guid(guid);
    106 
    107   std::set<std::string> current_profiles;
    108 
    109   // This will be released inside the function
    110   // TraverseAndAssociateChromeAutofillProfiles
    111   AutofillProfile *profile = new AutofillProfile(guid);
    112 
    113   // Set up the entry kernel with what we want.
    114   EntryKernel kernel;
    115   kernel.put(syncable::SPECIFICS, specifics);
    116   kernel.put(syncable::META_HANDLE, 1);
    117 
    118   MockWriteTransaction write_trans(&mock_directory);
    119   EXPECT_CALL(mock_directory, GetEntryByClientTag(_))
    120              .WillOnce(Return(&kernel));
    121 
    122   sync_api::ReadNode read_node(&write_trans);
    123 
    124   EXPECT_CALL(associator_, Associate(Pointee(guid), 1));
    125 
    126   profiles_from_web_db.push_back(profile);
    127 
    128   associator_.TraverseAndAssociateChromeAutofillProfilesWrapper(&write_trans,
    129       read_node,
    130       profiles_from_web_db.get(),
    131       &current_profiles,
    132       NULL,
    133       NULL,
    134       NULL);
    135 
    136   EXPECT_EQ((unsigned int)1, current_profiles.size());
    137 }
    138 
    139 TEST_F(AutofillProfileModelAssociatorTest, TestAssociatingMissingWebDBProfile) {
    140   ScopedVector<AutofillProfile> profiles_from_web_db;
    141   MockDirectory mock_directory;
    142 
    143   MockWriteTransaction write_trans(&mock_directory);
    144   EXPECT_CALL(mock_directory,
    145               GetEntryByClientTag(_))
    146              .WillOnce(Return(reinterpret_cast<EntryKernel*>(NULL)));
    147 
    148   sync_api::ReadNode autofill_root(&write_trans);
    149 
    150   std::string guid = "EDC609ED-7EEE-4F27-B00C-423242A9C44A";
    151   std::set<std::string> current_profiles;
    152   AutofillProfile *profile = new AutofillProfile(guid);
    153 
    154   EXPECT_CALL(associator_,
    155               MakeNewAutofillProfileSyncNodeIfNeeded(&write_trans,
    156                                              Ref(autofill_root),
    157                                              Ref(*profile),
    158                                              _,
    159                                              &current_profiles,
    160                                              NULL))
    161               .WillOnce(Return(true));
    162 
    163   profiles_from_web_db.push_back(profile);
    164 
    165   associator_.TraverseAndAssociateChromeAutofillProfilesWrapper(&write_trans,
    166       autofill_root,
    167       profiles_from_web_db.get(),
    168       &current_profiles,
    169       NULL,
    170       NULL,
    171       NULL);
    172 }
    173 
    174 TEST_F(AutofillProfileModelAssociatorTest,
    175     TestAssociateProfileInSyncDBWithWebDB) {
    176   ReadNodeMock autofill_root;
    177 
    178   // The constrcutor itself will initialize the id to root.
    179   syncable::Id root_id;
    180 
    181   sync_pb::EntitySpecifics specifics;
    182   MockDirectory mock_directory;
    183   sync_pb::AutofillProfileSpecifics *profile_specifics =
    184       specifics.MutableExtension(sync_pb::autofill_profile);
    185 
    186   profile_specifics->set_guid("abc");
    187 
    188   // Set up the entry kernel with what we want.
    189   EntryKernel kernel;
    190   kernel.put(syncable::SPECIFICS, specifics);
    191   kernel.put(syncable::META_HANDLE, 1);
    192   kernel.put(syncable::ID, root_id);
    193 
    194   MockWriteTransaction write_trans(&mock_directory);
    195 
    196   browser_sync::AutofillProfileModelAssociator::DataBundle bundle;
    197 
    198   EXPECT_CALL(autofill_root, GetFirstChildId())
    199               .WillOnce(Return(1));
    200 
    201   EXPECT_CALL(mock_directory,
    202               GetEntryByHandle(_))
    203              .WillOnce(Return(&kernel));
    204 
    205   EXPECT_CALL(associator_,
    206     AddNativeProfileIfNeeded(_,
    207         &bundle,
    208         _));
    209 
    210   associator_.TraverseAndAssociateAllSyncNodesWrapper(&write_trans,
    211       autofill_root,
    212       &bundle);
    213 }
    214 
    215 TEST_F(AutofillProfileModelAssociatorTest, TestDontNeedToAddNativeProfile) {
    216   ::testing::StrictMock<MockAutofillProfileModelAssociator> associator;
    217   sync_pb::AutofillProfileSpecifics profile_specifics;
    218   ReadNodeMock read_node;
    219   std::string guid = "EDC609ED-7EEE-4F27-B00C-423242A9C44C";
    220   std::set<std::string> current_profiles;
    221   browser_sync::AutofillProfileModelAssociator::DataBundle bundle;
    222 
    223   profile_specifics.set_guid(guid);
    224 
    225   bundle.current_profiles.insert(guid);
    226 
    227   // We have no expectations to set. We have used a strict mock.
    228   // If the profile is already present no other function
    229   // should be called.
    230   associator.AddNativeProfileIfNeededWrapper(profile_specifics, &bundle,
    231       read_node);
    232 }
    233 
    234 TEST_F(AutofillProfileModelAssociatorTest, TestNeedToAddNativeProfile) {
    235   sync_pb::AutofillProfileSpecifics profile_specifics;
    236   ReadNodeMock read_node;
    237   std::string guid = "EDC609ED-7EEE-4F27-B00C-423242A9C44D";
    238   std::set<std::string> current_profiles;
    239   browser_sync::AutofillProfileModelAssociator::DataBundle bundle;
    240   std::string first_name = "lingesh";
    241 
    242   profile_specifics.set_guid(guid);
    243   profile_specifics.set_name_first(first_name);
    244 
    245   EXPECT_CALL(read_node, GetId())
    246               .WillOnce(Return(1));
    247 
    248   EXPECT_CALL(associator_,
    249     Associate(Pointee(guid), 1));
    250 
    251   associator_.AddNativeProfileIfNeededWrapper(
    252       profile_specifics,
    253       &bundle,
    254       read_node);
    255 
    256   EXPECT_EQ(bundle.new_profiles.size(), (unsigned int)1);
    257   EXPECT_EQ(bundle.new_profiles.front()->GetInfo(NAME_FIRST),
    258             UTF8ToUTF16(first_name));
    259 }
    260 
    261