Index: chrome/browser/sync/glue/autofill_profile_model_associator_unittest.cc |
diff --git a/chrome/browser/sync/glue/autofill_profile_model_associator_unittest.cc b/chrome/browser/sync/glue/autofill_profile_model_associator_unittest.cc |
new file mode 100755 |
index 0000000000000000000000000000000000000000..ee26956905b45a39d87890ffe246b04e92d4679a |
--- /dev/null |
+++ b/chrome/browser/sync/glue/autofill_profile_model_associator_unittest.cc |
@@ -0,0 +1,283 @@ |
+// Copyright (c) 2010 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "base/utf_string_conversions.h" |
+#include "chrome/browser/sync/engine/read_node_mock.h" |
+#include "chrome/browser/sync/glue/autofill_profile_model_associator.h" |
+#include "chrome/browser/sync/syncable/syncable.h" |
+#include "testing/gmock/include/gmock/gmock.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+using ::testing::_; |
+using ::testing::Return; |
+using ::testing::DoDefault; |
+using ::testing::ReturnRef; |
+using ::testing::Pointee; |
+using ::testing::Ref; |
+using ::testing::Invoke; |
+class AutoFillProfile; |
+ |
+using browser_sync::AutofillProfileModelAssociator; |
+ |
+using sync_api::WriteTransaction; |
+using syncable::Directory; |
+using syncable::EntryKernel; |
+ |
+class MockDirectory : public Directory { |
+public: |
+ MockDirectory() { |
+ init_kernel("myk"); |
+ } |
+ MOCK_METHOD1(GetEntryById, syncable::EntryKernel* (int64 id)); |
+ MOCK_METHOD1(GetEntryByClientTag, |
+ syncable::EntryKernel* (const std::string&)); |
+}; |
+ |
+class MockSyncableWriteTransaction : public syncable::WriteTransaction { |
+ public: |
+ MockSyncableWriteTransaction(Directory *directory) : |
+ WriteTransaction(directory, syncable::SYNCER, "dontcare.cpp", 25) { |
+ } |
+}; |
+ |
+class MockWriteTransaction : public sync_api::WriteTransaction { |
+ public: |
+ MockWriteTransaction(Directory* directory) : sync_api::WriteTransaction() { |
+ this->transaction_ = new MockSyncableWriteTransaction(directory); |
+ } |
+}; |
+ |
+ |
+// Note this is not a generic mock. This is a mock used to |
+// test AutofillProfileModelAssociator class itself by mocking |
+// other functions that are called by the functions we need to test. |
+class MockAutofillProfileModelAssociator : |
+ public AutofillProfileModelAssociator |
+{ |
+ public: |
+ MockAutofillProfileModelAssociator() { |
+ ON_CALL(*this, EnsureOnThread(_)) |
+ .WillByDefault(Return(true)); |
+ |
+ dontCheckThreadOnExit_ = true; |
+ } |
+ virtual ~MockAutofillProfileModelAssociator() {} |
+ bool TraverseAndAssociateChromeAutoFillProfilesWrapper( |
+ sync_api::WriteTransaction* write_trans, |
+ const sync_api::ReadNode& autofill_root, |
+ const std::vector<AutoFillProfile*>& all_profiles_from_db, |
+ std::set<std::string>* current_profiles, |
+ std::vector<AutoFillProfile*>* updated_profiles) |
+ { |
+ return TraverseAndAssociateChromeAutoFillProfiles( |
+ write_trans, |
+ autofill_root, |
+ all_profiles_from_db, |
+ current_profiles, |
+ updated_profiles); |
+ } |
+ MOCK_METHOD3(AddNativeProfileIfNeeded, |
+ void(const sync_pb::AutofillProfile2Specifics& profile, |
+ DataBundle* bundle, |
+ const sync_api::ReadNode& node)); |
+ MOCK_METHOD2(OverwriteProfileWithServerData, |
+ bool(AutoFillProfile* merge_into, |
+ const sync_pb::AutofillProfile2Specifics& specifics)); |
+ MOCK_METHOD4(MakeNewAutofillProfileSyncNode, |
+ bool( sync_api::WriteTransaction* trans, |
+ const sync_api::BaseNode& autofill_root, |
+ const AutoFillProfile& profile, |
+ int64* sync_id)); |
+ MOCK_METHOD2(Associate, void(const std::string* autofill, int64 id)); |
+ MOCK_METHOD1(EnsureOnThread, bool(BrowserThread::ID)); |
+ |
+ bool TraverseAndAssociateAllSyncNodesWrapper( |
+ sync_api::WriteTransaction *trans, |
+ const sync_api::ReadNode &autofill_root, |
+ browser_sync::AutofillProfileModelAssociator::DataBundle *bundle) |
+ { |
+ return TraverseAndAssociateAllSyncNodes(trans, autofill_root, bundle); |
+ } |
+ |
+ void AddNativeProfileIfNeededWrapper( |
+ const sync_pb::AutofillProfile2Specifics& profile, |
+ DataBundle* bundle, |
+ const sync_api::ReadNode& node) |
+ { |
+ AutofillProfileModelAssociator::AddNativeProfileIfNeeded( |
+ profile, |
+ bundle, |
+ node); |
+ } |
+}; |
+ |
+bool SetSyncId(sync_api::WriteTransaction* trans, |
+ const sync_api::BaseNode& autofill_root, |
+ const AutoFillProfile& profile, |
+ int64* sync_id) |
+{ |
+ *sync_id = (int64)1; |
+ return true; |
+} |
+ |
+TEST(AutofillProfile2Test, TestAssociateProfileInWebDBWithSyncDB) |
+{ |
+ MockAutofillProfileModelAssociator associator; |
+ ScopedVector<AutoFillProfile> profiles_from_web_db; |
+ std::string guid = "abc"; |
+ |
+ sync_pb::EntitySpecifics specifics; |
+ MockDirectory mock_directory; |
+ sync_pb::AutofillProfile2Specifics *profile_specifics = |
+ specifics.MutableExtension(sync_pb::autofill_profile); |
+ |
+ profile_specifics->set_guid(guid); |
+ |
+ std::set<std::string> current_profiles; |
+ AutoFillProfile *profile = new AutoFillProfile(guid); |
+ |
+ // Set up the entry kernel with what we want. |
+ EntryKernel kernel; |
+ kernel.put(syncable::SPECIFICS, specifics); |
+ kernel.put(syncable::META_HANDLE, (int64)1); |
+ |
+ MockWriteTransaction write_trans(&mock_directory); |
+ EXPECT_CALL(mock_directory, |
+ GetEntryByClientTag(_)) |
+ .WillOnce(Return(&kernel)); |
+ |
+ sync_api::ReadNode read_node(&write_trans); |
+ |
+ EXPECT_CALL(associator, Associate(Pointee(guid), (int64)1)); |
+ |
+ profiles_from_web_db.push_back(profile); |
+ |
+ associator.TraverseAndAssociateChromeAutoFillProfilesWrapper(&write_trans, |
+ read_node, |
+ profiles_from_web_db.get(), |
+ ¤t_profiles, |
+ NULL); |
+ |
+ EXPECT_EQ(1, current_profiles.size()); |
+} |
+ |
+TEST(AutofillProfile2Test, TestAssociatingMissingWebDBProfile) |
+{ |
+ MockAutofillProfileModelAssociator associator; |
+ ScopedVector<AutoFillProfile> profiles_from_web_db; |
+ sync_pb::AutofillProfile2Specifics profile_specifics; |
+ |
+ // Will be released inside the function |
+ // TraverseAndAssociateChromeAutoFillProfilesWrapper |
+ ReadNodeMock *read_node = new ReadNodeMock(); |
+ std::string guid = "abc"; |
+ std::set<std::string> current_profiles; |
+ AutoFillProfile *profile = new AutoFillProfile(guid); |
+ |
+ profile_specifics.set_guid(guid); |
+ |
+ // EXPECT_CALL(associator, GetReadNode(_)) |
+ // .WillOnce(Return(read_node)); |
+ |
+ EXPECT_CALL(*read_node, |
+ InitByClientTagLookup(syncable::AUTOFILL_PROFILE, guid)) |
+ .WillOnce(Return(false)); |
+ |
+ EXPECT_CALL(associator, |
+ MakeNewAutofillProfileSyncNode(NULL, |
+ Ref(*read_node), |
+ Ref(*profile), _)) |
+ .WillOnce(Invoke(SetSyncId)); |
+ |
+ EXPECT_CALL(associator, Associate(Pointee(guid), (int64)1)); |
+ |
+ profiles_from_web_db.push_back(profile); |
+ |
+ associator.TraverseAndAssociateChromeAutoFillProfilesWrapper(NULL, |
+ *read_node, |
+ profiles_from_web_db.get(), |
+ ¤t_profiles, |
+ NULL); |
+ |
+ EXPECT_EQ(1, current_profiles.size()); |
+} |
+ |
+TEST(AutofillProfile2Test, TestAssociateProfileInSyncDBWithWebDB) |
+{ |
+ MockAutofillProfileModelAssociator associator; |
+ ReadNodeMock *read_node = new ReadNodeMock(); |
+ ReadNodeMock autofill_root; |
+ sync_pb::AutofillProfile2Specifics profile_specifics; |
+ |
+ browser_sync::AutofillProfileModelAssociator::DataBundle bundle; |
+ |
+ EXPECT_CALL(autofill_root, GetFirstChildId()) |
+ .WillOnce(Return((int64)1)); |
+ |
+ // EXPECT_CALL(associator, GetReadNode(_)) |
+ // .WillOnce(Return(read_node)); |
+ |
+ EXPECT_CALL(*read_node, InitByIdLookup((int64)1)) |
+ .WillOnce(Return(true)); |
+ |
+ EXPECT_CALL(*read_node, GetAutofillProfileSpecifics()) |
+ .WillOnce(ReturnRef(profile_specifics)); |
+ |
+ EXPECT_CALL(associator, |
+ AddNativeProfileIfNeeded(Ref(profile_specifics), |
+ &bundle, |
+ Ref(*read_node))); |
+ |
+ EXPECT_CALL(*read_node, GetSuccessorId()) |
+ .WillOnce(Return(sync_api::kInvalidId)); |
+ |
+ associator.TraverseAndAssociateAllSyncNodesWrapper(NULL, |
+ autofill_root, |
+ &bundle); |
+} |
+ |
+TEST(AutofillProfile2Test, TestDontNeedToAddNativeProfile) |
+{ |
+ MockAutofillProfileModelAssociator associator; |
+ sync_pb::AutofillProfile2Specifics profile_specifics; |
+ ReadNodeMock read_node; |
+ std::string guid = "abc"; |
+ std::set<std::string> current_profiles; |
+ AutoFillProfile *profile = new AutoFillProfile(guid); |
+ browser_sync::AutofillProfileModelAssociator::DataBundle bundle; |
+ |
+ bundle.current_profiles.insert(guid); |
+ |
+ // We have no expectations to set. |
+ // If the profile is already present no other function |
+ // should be called. |
+ associator.AddNativeProfileIfNeededWrapper(profile_specifics, &bundle, read_node); |
+} |
+ |
+TEST(AutofillProfile2Test, TestNeedToAddNativeProfile) |
+{ |
+ MockAutofillProfileModelAssociator associator; |
+ sync_pb::AutofillProfile2Specifics profile_specifics; |
+ ReadNodeMock read_node; |
+ std::string guid = "abc"; |
+ std::set<std::string> current_profiles; |
+ AutoFillProfile *profile = new AutoFillProfile(guid); |
+ browser_sync::AutofillProfileModelAssociator::DataBundle bundle; |
+ std::string first_name = "lingesh"; |
+ |
+ profile_specifics.set_guid(guid); |
+ profile_specifics.set_name_first(first_name); |
+ |
+ EXPECT_CALL(read_node, GetId()) |
+ .WillOnce(Return((int64)1)); |
+ |
+ EXPECT_CALL(associator, Associate(Pointee(guid), (int64)1)); |
+ |
+ associator.AddNativeProfileIfNeededWrapper(profile_specifics, &bundle, read_node); |
+ |
+ EXPECT_EQ(bundle.new_profiles.size(), 1); |
+ EXPECT_EQ( |
+ bundle.new_profiles.front()->GetFieldText(AutoFillType(NAME_FIRST)), |
+ UTF8ToUTF16(first_name)); |
+} |