| 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));
|
| +}
|
|
|