Commit d85e92e5 authored by sebsg's avatar sebsg Committed by Commit Bot

[AF USS] Implement GetAllDataForDebugging for the wallet data bridge.

Bug: 853688
Change-Id: Ibac26f2adab7a360d866e3abc75b36f0bab8ab51
Reviewed-on: https://chromium-review.googlesource.com/1152085
Commit-Queue: Sebastien Seguin-Gagnon <sebsg@chromium.org>
Reviewed-by: default avatarJan Krcal <jkrcal@chromium.org>
Cr-Commit-Position: refs/heads/master@{#580896}
parent dee84071
......@@ -176,6 +176,8 @@ static_library("browser") {
"webdata/autofill_profile_sync_difference_tracker.h",
"webdata/autofill_profile_syncable_service.cc",
"webdata/autofill_profile_syncable_service.h",
"webdata/autofill_sync_bridge_util.cc",
"webdata/autofill_sync_bridge_util.h",
"webdata/autofill_table.cc",
"webdata/autofill_table.h",
"webdata/autofill_table_encryptor.h",
......@@ -333,6 +335,8 @@ static_library("test_support") {
"test_region_data_loader.h",
"test_sync_service.cc",
"test_sync_service.h",
"webdata/autofill_sync_bridge_test_util.cc",
"webdata/autofill_sync_bridge_test_util.h",
]
public_deps = [
......
// Copyright 2018 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 "components/autofill/core/browser/webdata/autofill_sync_bridge_test_util.h"
namespace autofill {
AutofillProfile CreateServerProfile(const std::string& server_id) {
// TODO(sebsg): Set data.
return AutofillProfile(AutofillProfile::SERVER_PROFILE, server_id);
}
CreditCard CreateServerCreditCard(const std::string& server_id) {
// TODO(sebsg): Set data.
return CreditCard(CreditCard::MASKED_SERVER_CARD, server_id);
}
} // namespace autofill
\ No newline at end of file
// Copyright 2018 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.
#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_WEBDATA_AUTOFILL_SYNC_BRIDGE_TEST_UTIL_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_WEBDATA_AUTOFILL_SYNC_BRIDGE_TEST_UTIL_H_
#include <string>
#include "components/autofill/core/browser/autofill_profile.h"
#include "components/autofill/core/browser/credit_card.h"
namespace autofill {
AutofillProfile CreateServerProfile(const std::string& server_id);
CreditCard CreateServerCreditCard(const std::string& server_id);
} // namespace autofill
#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_WEBDATA_AUTOFILL_SYNC_BRIDGE_TEST_UTIL_H_
// Copyright 2018 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 "components/autofill/core/browser/webdata/autofill_sync_bridge_util.h"
#include "base/base64.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/browser/autofill_profile.h"
#include "components/autofill/core/browser/credit_card.h"
#include "components/autofill/core/browser/webdata/autofill_table.h"
#include "components/sync/model/entity_data.h"
using sync_pb::AutofillWalletSpecifics;
using syncer::EntityData;
namespace autofill {
namespace {
std::string TruncateUTF8(const std::string& data) {
std::string trimmed_value;
base::TruncateUTF8ToByteSize(data, AutofillTable::kMaxDataLength,
&trimmed_value);
return trimmed_value;
}
sync_pb::WalletMaskedCreditCard::WalletCardStatus LocalToServerStatus(
const CreditCard& card) {
switch (card.GetServerStatus()) {
case CreditCard::OK:
return sync_pb::WalletMaskedCreditCard::VALID;
case CreditCard::EXPIRED:
default:
return sync_pb::WalletMaskedCreditCard::EXPIRED;
}
}
sync_pb::WalletMaskedCreditCard::WalletCardType WalletCardTypeFromCardNetwork(
const std::string& network) {
if (network == kAmericanExpressCard)
return sync_pb::WalletMaskedCreditCard::AMEX;
if (network == kDiscoverCard)
return sync_pb::WalletMaskedCreditCard::DISCOVER;
if (network == kJCBCard)
return sync_pb::WalletMaskedCreditCard::JCB;
if (network == kMasterCard)
return sync_pb::WalletMaskedCreditCard::MASTER_CARD;
if (network == kUnionPay)
return sync_pb::WalletMaskedCreditCard::UNIONPAY;
if (network == kVisaCard)
return sync_pb::WalletMaskedCreditCard::VISA;
// Some cards aren't supported by the client, so just return unknown.
return sync_pb::WalletMaskedCreditCard::UNKNOWN;
}
sync_pb::WalletMaskedCreditCard::WalletCardClass WalletCardClassFromCardType(
CreditCard::CardType card_type) {
switch (card_type) {
case CreditCard::CARD_TYPE_CREDIT:
return sync_pb::WalletMaskedCreditCard::CREDIT;
case CreditCard::CARD_TYPE_DEBIT:
return sync_pb::WalletMaskedCreditCard::DEBIT;
case CreditCard::CARD_TYPE_PREPAID:
return sync_pb::WalletMaskedCreditCard::PREPAID;
default:
return sync_pb::WalletMaskedCreditCard::UNKNOWN_CARD_CLASS;
}
}
} // namespace
std::string GetSpecificsIdForEntryServerId(const std::string& server_id) {
std::string specifics_id;
base::Base64Encode(server_id, &specifics_id);
return specifics_id;
}
std::string GetStorageKeyForSpecificsId(const std::string& specifics_id) {
// We use the base64 encoded |specifics_id| directly as the storage key, this
// function only hides this definition from all its call sites.
return specifics_id;
}
std::string GetStorageKeyForEntryServerId(const std::string& server_id) {
return GetStorageKeyForSpecificsId(GetSpecificsIdForEntryServerId(server_id));
}
std::string GetClientTagForSpecificsId(
AutofillWalletSpecifics::WalletInfoType type,
const std::string& wallet_data_specifics_id) {
switch (type) {
case AutofillWalletSpecifics::POSTAL_ADDRESS:
return "address-" + wallet_data_specifics_id;
case AutofillWalletSpecifics::MASKED_CREDIT_CARD:
return "card-" + wallet_data_specifics_id;
case sync_pb::AutofillWalletSpecifics::CUSTOMER_DATA:
return "customer-" + wallet_data_specifics_id;
case AutofillWalletSpecifics::UNKNOWN:
NOTREACHED();
return "";
}
}
void SetAutofillWalletSpecificsFromServerProfile(
const AutofillProfile& address,
AutofillWalletSpecifics* wallet_specifics) {
wallet_specifics->set_type(AutofillWalletSpecifics::POSTAL_ADDRESS);
sync_pb::WalletPostalAddress* wallet_address =
wallet_specifics->mutable_address();
wallet_address->set_id(address.server_id());
wallet_address->set_language_code(TruncateUTF8(address.language_code()));
if (address.HasRawInfo(NAME_FULL)) {
wallet_address->set_recipient_name(
TruncateUTF8(base::UTF16ToUTF8(address.GetRawInfo(NAME_FULL))));
}
if (address.HasRawInfo(COMPANY_NAME)) {
wallet_address->set_company_name(
TruncateUTF8(base::UTF16ToUTF8(address.GetRawInfo(COMPANY_NAME))));
}
if (address.HasRawInfo(ADDRESS_HOME_STREET_ADDRESS)) {
wallet_address->add_street_address(TruncateUTF8(
base::UTF16ToUTF8(address.GetRawInfo(ADDRESS_HOME_STREET_ADDRESS))));
}
if (address.HasRawInfo(ADDRESS_HOME_STATE)) {
wallet_address->set_address_1(TruncateUTF8(
base::UTF16ToUTF8(address.GetRawInfo(ADDRESS_HOME_STATE))));
}
if (address.HasRawInfo(ADDRESS_HOME_CITY)) {
wallet_address->set_address_2(
TruncateUTF8(base::UTF16ToUTF8(address.GetRawInfo(ADDRESS_HOME_CITY))));
}
if (address.HasRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY)) {
wallet_address->set_address_3(TruncateUTF8(base::UTF16ToUTF8(
address.GetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY))));
}
if (address.HasRawInfo(ADDRESS_HOME_ZIP)) {
wallet_address->set_postal_code(
TruncateUTF8(base::UTF16ToUTF8(address.GetRawInfo(ADDRESS_HOME_ZIP))));
}
if (address.HasRawInfo(ADDRESS_HOME_COUNTRY)) {
wallet_address->set_country_code(TruncateUTF8(
base::UTF16ToUTF8(address.GetRawInfo(ADDRESS_HOME_COUNTRY))));
}
if (address.HasRawInfo(PHONE_HOME_WHOLE_NUMBER)) {
wallet_address->set_phone_number(TruncateUTF8(
base::UTF16ToUTF8(address.GetRawInfo(PHONE_HOME_WHOLE_NUMBER))));
}
if (address.HasRawInfo(ADDRESS_HOME_SORTING_CODE)) {
wallet_address->set_sorting_code(TruncateUTF8(
base::UTF16ToUTF8(address.GetRawInfo(ADDRESS_HOME_SORTING_CODE))));
}
}
std::unique_ptr<EntityData> CreateEntityDataFromAutofillServerProfile(
const AutofillProfile& address) {
auto entity_data = std::make_unique<EntityData>();
std::string specifics_id =
GetSpecificsIdForEntryServerId(address.server_id());
entity_data->non_unique_name = GetClientTagForSpecificsId(
AutofillWalletSpecifics::POSTAL_ADDRESS, specifics_id);
AutofillWalletSpecifics* wallet_specifics =
entity_data->specifics.mutable_autofill_wallet();
SetAutofillWalletSpecificsFromServerProfile(address, wallet_specifics);
return entity_data;
}
void SetAutofillWalletSpecificsFromServerCard(
const CreditCard& card,
AutofillWalletSpecifics* wallet_specifics) {
wallet_specifics->set_type(AutofillWalletSpecifics::MASKED_CREDIT_CARD);
sync_pb::WalletMaskedCreditCard* wallet_card =
wallet_specifics->mutable_masked_card();
wallet_card->set_id(card.server_id());
wallet_card->set_status(LocalToServerStatus(card));
if (card.HasRawInfo(CREDIT_CARD_NAME_FULL)) {
wallet_card->set_name_on_card(TruncateUTF8(
base::UTF16ToUTF8(card.GetRawInfo(CREDIT_CARD_NAME_FULL))));
}
wallet_card->set_type(WalletCardTypeFromCardNetwork(card.network()));
wallet_card->set_last_four(base::UTF16ToUTF8(card.LastFourDigits()));
wallet_card->set_exp_month(card.expiration_month());
wallet_card->set_exp_year(card.expiration_year());
wallet_card->set_billing_address_id(card.billing_address_id());
wallet_card->set_card_class(WalletCardClassFromCardType(card.card_type()));
wallet_card->set_bank_name(card.bank_name());
}
std::unique_ptr<EntityData> CreateEntityDataFromCard(const CreditCard& card) {
std::string specifics_id = GetSpecificsIdForEntryServerId(card.server_id());
auto entity_data = std::make_unique<EntityData>();
entity_data->non_unique_name = GetClientTagForSpecificsId(
AutofillWalletSpecifics::MASKED_CREDIT_CARD, specifics_id);
AutofillWalletSpecifics* wallet_specifics =
entity_data->specifics.mutable_autofill_wallet();
SetAutofillWalletSpecificsFromServerCard(card, wallet_specifics);
return entity_data;
}
} // namespace autofill
\ No newline at end of file
// Copyright 2018 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.
#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_WEBDATA_AUTOFILL_SYNC_BRIDGE_UTIL_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_WEBDATA_AUTOFILL_SYNC_BRIDGE_UTIL_H_
#include <memory>
#include <string>
#include "components/sync/model/entity_data.h"
namespace autofill {
class AutofillProfile;
class CreditCard;
// Returns the wallet specifics id for the specified |server_id|.
std::string GetSpecificsIdForEntryServerId(const std::string& server_id);
// Returns the storage key for the specified |server_id|.
std::string GetStorageKeyForSpecificsId(const std::string& specifics_id);
// Returns the wallet specifics storage key for the specified |server_id|.
std::string GetStorageKeyForEntryServerId(const std::string& server_id);
// Returns the client tag for the specified wallet |type| and
// |wallet_data_specifics_id|.
std::string GetClientTagForSpecificsId(
sync_pb::AutofillWalletSpecifics::WalletInfoType type,
const std::string& wallet_data_specifics_id);
// Sets the fields of the |wallet_specifics| based on the the specified
// |address|.
void SetAutofillWalletSpecificsFromServerProfile(
const AutofillProfile& address,
sync_pb::AutofillWalletSpecifics* wallet_specifics);
// Creates a EntityData object corresponding to the specified |address|.
std::unique_ptr<syncer::EntityData> CreateEntityDataFromAutofillServerProfile(
const AutofillProfile& address);
// Sets the fields of the |wallet_specifics| based on the the specified |card|.
void SetAutofillWalletSpecificsFromServerCard(
const CreditCard& card,
sync_pb::AutofillWalletSpecifics* wallet_specifics);
// Creates a EntityData object corresponding to the specified |card|.
std::unique_ptr<syncer::EntityData> CreateEntityDataFromCard(
const CreditCard& card);
} // namespace autofill
#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_WEBDATA_AUTOFILL_SYNC_BRIDGE_UTIL_H_
......@@ -12,6 +12,7 @@
#include "base/optional.h"
#include "components/autofill/core/browser/autofill_profile.h"
#include "components/autofill/core/browser/credit_card.h"
#include "components/autofill/core/browser/webdata/autofill_sync_bridge_util.h"
#include "components/autofill/core/browser/webdata/autofill_table.h"
#include "components/autofill/core/browser/webdata/autofill_webdata_backend.h"
#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
......@@ -42,22 +43,6 @@ std::string GetClientTagForSpecificsId(WalletMetadataSpecifics::Type type,
}
}
std::string GetSpecificsIdForEntryServerId(const std::string& server_id) {
std::string specifics_id;
base::Base64Encode(server_id, &specifics_id);
return specifics_id;
}
std::string GetStorageKeyForSpecificsId(const std::string& specifics_id) {
// We use the base64 encoded |specifics_id| directly as the storage key, this
// function only hides this definition from all its call sites.
return specifics_id;
}
std::string GetStorageKeyForEntryServerId(const std::string& server_id) {
return GetStorageKeyForSpecificsId(GetSpecificsIdForEntryServerId(server_id));
}
// Returns EntityData with common fields set based on |local_data_model|.
std::unique_ptr<EntityData> CreateEntityDataFromAutofillDataModel(
const AutofillDataModel& local_data_model,
......
......@@ -7,6 +7,7 @@
#include <memory>
#include <string>
#include <unordered_set>
#include "base/macros.h"
#include "base/sequence_checker.h"
......
......@@ -22,6 +22,7 @@
#include "components/autofill/core/browser/country_names.h"
#include "components/autofill/core/browser/credit_card.h"
#include "components/autofill/core/browser/test_autofill_clock.h"
#include "components/autofill/core/browser/webdata/autofill_sync_bridge_test_util.h"
#include "components/autofill/core/browser/webdata/autofill_table.h"
#include "components/autofill/core/browser/webdata/autofill_webdata_backend.h"
#include "components/autofill/core/common/autofill_constants.h"
......@@ -115,14 +116,6 @@ WalletMetadataSpecifics CreateWalletMetadataSpecificsForCard(
return specifics;
}
AutofillProfile CreateServerProfile(const std::string& server_id) {
return AutofillProfile(AutofillProfile::SERVER_PROFILE, server_id);
}
CreditCard CreateCreditCard(const std::string& server_id) {
return CreditCard(CreditCard::MASKED_SERVER_CARD, server_id);
}
void ExtractWalletMetadataSpecificsFromDataBatch(
std::unique_ptr<DataBatch> batch,
std::vector<WalletMetadataSpecifics>* output) {
......@@ -290,8 +283,8 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest,
GetAllDataForDebugging_ShouldReturnAllData) {
table()->SetServerProfiles({CreateServerProfile(kAddr1ServerId),
CreateServerProfile(kAddr2ServerId)});
table()->SetServerCreditCards(
{CreateCreditCard(kCard1ServerId), CreateCreditCard(kCard2ServerId)});
table()->SetServerCreditCards({CreateServerCreditCard(kCard1ServerId),
CreateServerCreditCard(kCard2ServerId)});
EXPECT_THAT(
GetAllLocalData(),
......@@ -314,8 +307,8 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest,
TEST_F(AutofillWalletMetadataSyncBridgeTest, GetData_ShouldReturnSelectedData) {
table()->SetServerProfiles({CreateServerProfile(kAddr1ServerId),
CreateServerProfile(kAddr2ServerId)});
table()->SetServerCreditCards(
{CreateCreditCard(kCard1ServerId), CreateCreditCard(kCard2ServerId)});
table()->SetServerCreditCards({CreateServerCreditCard(kCard1ServerId),
CreateServerCreditCard(kCard2ServerId)});
EXPECT_THAT(GetLocalData({kAddr1SpecificsId, kCard1SpecificsId}),
UnorderedElementsAre(
......@@ -333,7 +326,7 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest, GetData_ShouldReturnCompleteData) {
profile.set_has_converted(true);
table()->SetServerProfiles({profile});
CreditCard card = CreateCreditCard(kCard1ServerId);
CreditCard card = CreateServerCreditCard(kCard1ServerId);
card.set_use_count(6);
card.set_use_date(base::Time::FromDeltaSinceWindowsEpoch(
base::TimeDelta::FromMicroseconds(3)));
......
......@@ -4,17 +4,26 @@
#include "components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.h"
#include <memory>
#include <utility>
#include "base/base64.h"
#include "base/logging.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/browser/autofill_profile.h"
#include "components/autofill/core/browser/autofill_profile_sync_util.h"
#include "components/autofill/core/browser/credit_card.h"
#include "components/autofill/core/browser/webdata/autofill_sync_bridge_util.h"
#include "components/autofill/core/browser/webdata/autofill_table.h"
#include "components/autofill/core/browser/webdata/autofill_webdata_backend.h"
#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
#include "components/sync/model/entity_data.h"
#include "components/sync/model/mutable_data_batch.h"
#include "components/sync/model_impl/client_tag_based_model_type_processor.h"
#include "components/sync/model_impl/sync_metadata_store_change_list.h"
using sync_pb::AutofillWalletSpecifics;
using syncer::EntityData;
namespace autofill {
namespace {
......@@ -69,12 +78,12 @@ AutofillWalletSyncBridge::AutofillWalletSyncBridge(
web_data_backend_(web_data_backend) {}
AutofillWalletSyncBridge::~AutofillWalletSyncBridge() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}
std::unique_ptr<syncer::MetadataChangeList>
AutofillWalletSyncBridge::CreateMetadataChangeList() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return std::make_unique<syncer::SyncMetadataStoreChangeList>(
GetAutofillTable(), syncer::AUTOFILL_WALLET_DATA);
}
......@@ -95,29 +104,42 @@ base::Optional<syncer::ModelError> AutofillWalletSyncBridge::ApplySyncChanges(
void AutofillWalletSyncBridge::GetData(StorageKeyList storage_keys,
DataCallback callback) {
// This data type is never synced "up" so we don't need to implement this.
NOTIMPLEMENTED();
}
void AutofillWalletSyncBridge::GetAllDataForDebugging(DataCallback callback) {
NOTIMPLEMENTED();
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
std::vector<std::unique_ptr<AutofillProfile>> profiles;
std::vector<std::unique_ptr<CreditCard>> cards;
if (!GetAutofillTable()->GetServerProfiles(&profiles) ||
!GetAutofillTable()->GetServerCreditCards(&cards)) {
change_processor()->ReportError(
{FROM_HERE, "Failed to load entries from table."});
return;
}
auto batch = std::make_unique<syncer::MutableDataBatch>();
for (const std::unique_ptr<AutofillProfile>& entry : profiles) {
batch->Put(GetStorageKeyForEntryServerId(entry->server_id()),
CreateEntityDataFromAutofillServerProfile(*entry));
}
for (const std::unique_ptr<CreditCard>& entry : cards) {
batch->Put(GetStorageKeyForEntryServerId(entry->server_id()),
CreateEntityDataFromCard(*entry));
}
std::move(callback).Run(std::move(batch));
}
std::string AutofillWalletSyncBridge::GetClientTag(
const syncer::EntityData& entity_data) {
DCHECK(entity_data.specifics.has_autofill_wallet());
switch (entity_data.specifics.autofill_wallet().type()) {
case sync_pb::AutofillWalletSpecifics::POSTAL_ADDRESS:
return "address-" + GetStorageKey(entity_data);
case sync_pb::AutofillWalletSpecifics::MASKED_CREDIT_CARD:
return "card-" + GetStorageKey(entity_data);
case sync_pb::AutofillWalletSpecifics::CUSTOMER_DATA:
return "customer-" + GetStorageKey(entity_data);
case sync_pb::AutofillWalletSpecifics::UNKNOWN:
NOTREACHED();
return std::string();
}
return std::string();
return GetClientTagForSpecificsId(
entity_data.specifics.autofill_wallet().type(),
GetStorageKey(entity_data));
}
std::string AutofillWalletSyncBridge::GetStorageKey(
......
......@@ -7,10 +7,11 @@
#include <memory>
#include <string>
#include <unordered_set>
#include "base/macros.h"
#include "base/sequence_checker.h"
#include "base/supports_user_data.h"
#include "base/threading/thread_checker.h"
#include "components/sync/model/metadata_change_list.h"
#include "components/sync/model/model_error.h"
#include "components/sync/model/model_type_change_processor.h"
......@@ -58,15 +59,16 @@ class AutofillWalletSyncBridge : public base::SupportsUserData::Data,
std::string GetStorageKey(const syncer::EntityData& entity_data) override;
private:
// Returns the table associated with the |web_data_backend_|.
AutofillTable* GetAutofillTable();
// The bridge should be used on the same sequence where it is constructed.
THREAD_CHECKER(thread_checker_);
// AutofillProfileSyncBridge is owned by |web_data_backend_| through
// SupportsUserData, so it's guaranteed to outlive |this|.
AutofillWebDataBackend* const web_data_backend_;
// The bridge should be used on the same sequence where it is constructed.
SEQUENCE_CHECKER(sequence_checker_);
DISALLOW_COPY_AND_ASSIGN(AutofillWalletSyncBridge);
};
......
......@@ -12,11 +12,14 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/files/scoped_temp_dir.h"
#include "base/message_loop/message_loop.h"
#include "base/test/bind_test_util.h"
#include "base/test/scoped_task_environment.h"
#include "base/time/time.h"
#include "components/autofill/core/browser/country_names.h"
#include "components/autofill/core/browser/test_autofill_clock.h"
#include "components/autofill/core/browser/webdata/autofill_sync_bridge_test_util.h"
#include "components/autofill/core/browser/webdata/autofill_sync_bridge_util.h"
#include "components/autofill/core/browser/webdata/autofill_table.h"
#include "components/autofill/core/browser/webdata/autofill_webdata_backend.h"
#include "components/autofill/core/common/autofill_constants.h"
......@@ -35,16 +38,30 @@ namespace {
using base::ScopedTempDir;
using sync_pb::AutofillWalletSpecifics;
using syncer::DataBatch;
using syncer::EntityData;
using syncer::EntityDataPtr;
using syncer::KeyAndData;
using syncer::MockModelTypeChangeProcessor;
using syncer::ModelType;
using testing::UnorderedElementsAre;
// Base64 encoded SHA1 hash of all address fields.
const char kAddressHashA[] = "MgM+9iWXwMGwEpFfDDp06K3jizU=";
// Non-UTF8 server IDs.
const char kAddr1ServerId[] = "addr1\xEF\xBF\xBE";
const char kAddr2ServerId[] = "addr2\xEF\xBF\xBE";
const char kCard1ServerId[] = "card1\xEF\xBF\xBE";
const char kCard2ServerId[] = "card2\xEF\xBF\xBE";
// Base64 encoded string (opaque to Chrome; any such string works here).
const char kCardIdA[] = "AQIDBAECAwQBAgMEAQIDBAECAwQBAgMEAQIDBAECAwQBAgME";
// Base64 encodings of the server IDs, used as ids in WalletMetadataSpecifics
// (these are suitable for syncing, because they are valid UTF-8).
const char kAddr1SpecificsId[] = "YWRkcjHvv74=";
//const char kAddr2SpecificsId[] = "YWRkcjLvv74=";
const char kCard1SpecificsId[] = "Y2FyZDHvv74=";
//const char kCard2SpecificsId[] = "Y2FyZDLvv74=";
// Unique sync tags for the server IDs.
const char kAddr1SyncTag[] = "address-YWRkcjHvv74=";
const char kCard1SyncTag[] = "card-Y2FyZDHvv74=";
const char kLocaleString[] = "en-US";
const base::Time kJune2017 = base::Time::FromDoubleT(1497552271);
......@@ -69,7 +86,8 @@ class FakeAutofillBackend : public AutofillWebDataBackend {
WebDatabase* db_;
};
AutofillWalletSpecifics CreateWalletSpecificsForCard(const std::string& id) {
AutofillWalletSpecifics CreateAutofillWalletSpecificsForCard(
const std::string& specifics_id) {
sync_pb::AutofillWalletSpecifics wallet_specifics;
wallet_specifics.set_type(
sync_pb::AutofillWalletSpecifics_WalletInfoType::
......@@ -77,11 +95,12 @@ AutofillWalletSpecifics CreateWalletSpecificsForCard(const std::string& id) {
sync_pb::WalletMaskedCreditCard* card_specifics =
wallet_specifics.mutable_masked_card();
card_specifics->set_id(id);
card_specifics->set_id(specifics_id);
return wallet_specifics;
}
AutofillWalletSpecifics CreateWalletSpecificsForAddress(const std::string& id) {
AutofillWalletSpecifics CreateAutofillWalletSpecificsForAddress(
const std::string& specifics_id) {
sync_pb::AutofillWalletSpecifics wallet_specifics;
wallet_specifics.set_type(
sync_pb::AutofillWalletSpecifics_WalletInfoType::
......@@ -89,10 +108,86 @@ AutofillWalletSpecifics CreateWalletSpecificsForAddress(const std::string& id) {
sync_pb::WalletPostalAddress* address_specifics =
wallet_specifics.mutable_address();
address_specifics->set_id(id);
address_specifics->set_id(specifics_id);
return wallet_specifics;
}
void ExtractAutofillWalletSpecificsFromDataBatch(
std::unique_ptr<DataBatch> batch,
std::vector<AutofillWalletSpecifics>* output) {
while (batch->HasNext()) {
const KeyAndData& data_pair = batch->Next();
output->push_back(data_pair.second->specifics.autofill_wallet());
}
}
std::string WalletMaskedCreditCardSpecificsAsDebugString(
const AutofillWalletSpecifics& specifics) {
std::ostringstream output;
output << "[id: " << specifics.masked_card().id()
<< ", type: " << static_cast<int>(specifics.type())
<< ", name_on_card: " << specifics.masked_card().name_on_card()
<< ", type: " << specifics.masked_card().type()
<< ", last_four: " << specifics.masked_card().last_four()
<< ", exp_month: " << specifics.masked_card().exp_month()
<< ", exp_year: " << specifics.masked_card().exp_year()
<< ", billing_address_id: "
<< specifics.masked_card().billing_address_id()
<< ", card_class: " << specifics.masked_card().card_class()
<< ", bank_name: " << specifics.masked_card().bank_name() << "]";
return output.str();
}
std::string WalletPostalAddressSpecificsAsDebugString(
const AutofillWalletSpecifics& specifics) {
std::ostringstream output;
output << "[id: " << specifics.address().id()
<< ", type: " << static_cast<int>(specifics.type())
<< ", recipient_name: " << specifics.address().recipient_name()
<< ", company_name: " << specifics.address().company_name()
<< ", street_address: "
<< (specifics.address().street_address_size()
? specifics.address().street_address(0)
: "")
<< ", address_1: " << specifics.address().address_1()
<< ", address_2: " << specifics.address().address_2()
<< ", address_3: " << specifics.address().address_3()
<< ", postal_code: " << specifics.address().postal_code()
<< ", country_code: " << specifics.address().country_code()
<< ", phone_number: " << specifics.address().phone_number()
<< ", sorting_code: " << specifics.address().sorting_code() << "]";
return output.str();
}
std::string AutofillWalletSpecificsAsDebugString(
const AutofillWalletSpecifics& specifics) {
switch (specifics.type()) {
case sync_pb::AutofillWalletSpecifics_WalletInfoType::
AutofillWalletSpecifics_WalletInfoType_MASKED_CREDIT_CARD:
return WalletMaskedCreditCardSpecificsAsDebugString(specifics);
case sync_pb::AutofillWalletSpecifics_WalletInfoType::
AutofillWalletSpecifics_WalletInfoType_POSTAL_ADDRESS:
return WalletPostalAddressSpecificsAsDebugString(specifics);
case sync_pb::AutofillWalletSpecifics_WalletInfoType::
AutofillWalletSpecifics_WalletInfoType_CUSTOMER_DATA:
return "CustomerData";
case sync_pb::AutofillWalletSpecifics_WalletInfoType::
AutofillWalletSpecifics_WalletInfoType_UNKNOWN:
return "Unknown";
}
}
MATCHER_P(EqualsSpecifics, expected, "") {
if (arg.SerializeAsString() != expected.SerializeAsString()) {
*result_listener << "entry\n"
<< AutofillWalletSpecificsAsDebugString(arg) << "\n"
<< "did not match expected\n"
<< AutofillWalletSpecificsAsDebugString(expected);
return false;
}
return true;
}
} // namespace
class AutofillWalletSyncBridgeTest : public testing::Test {
......@@ -115,7 +210,7 @@ class AutofillWalletSyncBridgeTest : public testing::Test {
void ResetProcessor() {
real_processor_ =
std::make_unique<syncer::ClientTagBasedModelTypeProcessor>(
syncer::AUTOFILL_WALLET_METADATA, /*dump_stack=*/base::DoNothing(),
syncer::AUTOFILL_WALLET_DATA, /*dump_stack=*/base::DoNothing(),
/*commit_only=*/false);
mock_processor_.DelegateCallsByDefaultTo(real_processor_.get());
}
......@@ -129,7 +224,20 @@ class AutofillWalletSyncBridgeTest : public testing::Test {
EntityData data;
*data.specifics.mutable_autofill_wallet() = specifics;
data.client_tag_hash = syncer::GenerateSyncableHash(
syncer::AUTOFILL_WALLET_METADATA, bridge()->GetClientTag(data));
syncer::AUTOFILL_WALLET_DATA, bridge()->GetClientTag(data));
return data;
}
std::vector<AutofillWalletSpecifics> GetAllLocalData() {
std::vector<AutofillWalletSpecifics> data;
// Perform an async call synchronously for testing.
base::RunLoop loop;
bridge()->GetAllDataForDebugging(base::BindLambdaForTesting(
[&loop, &data](std::unique_ptr<DataBatch> batch) {
ExtractAutofillWalletSpecificsFromDataBatch(std::move(batch), &data);
loop.Quit();
}));
loop.Run();
return data;
}
......@@ -160,28 +268,56 @@ class AutofillWalletSyncBridgeTest : public testing::Test {
// The following 2 tests make sure client tags stay stable.
TEST_F(AutofillWalletSyncBridgeTest, GetClientTagForAddress) {
AutofillWalletSpecifics specifics =
CreateWalletSpecificsForAddress(kAddressHashA);
CreateAutofillWalletSpecificsForAddress(kAddr1SyncTag);
EXPECT_EQ(bridge()->GetClientTag(SpecificsToEntity(specifics)),
"address-" + std::string(kAddressHashA));
"address-" + std::string(kAddr1SyncTag));
}
TEST_F(AutofillWalletSyncBridgeTest, GetClientTagForCard) {
AutofillWalletSpecifics specifics = CreateWalletSpecificsForCard(kCardIdA);
AutofillWalletSpecifics specifics =
CreateAutofillWalletSpecificsForCard(kCard1SyncTag);
EXPECT_EQ(bridge()->GetClientTag(SpecificsToEntity(specifics)),
"card-" + std::string(kCardIdA));
"card-" + std::string(kCard1SyncTag));
}
// The following 2 tests make sure storage keys stay stable.
TEST_F(AutofillWalletSyncBridgeTest, GetStorageKeyForAddress) {
AutofillWalletSpecifics specifics1 =
CreateWalletSpecificsForAddress(kAddressHashA);
CreateAutofillWalletSpecificsForAddress(kAddr1SpecificsId);
EXPECT_EQ(bridge()->GetStorageKey(SpecificsToEntity(specifics1)),
kAddressHashA);
kAddr1SpecificsId);
}
TEST_F(AutofillWalletSyncBridgeTest, GetStorageKeyForCard) {
AutofillWalletSpecifics specifics2 = CreateWalletSpecificsForCard(kCardIdA);
EXPECT_EQ(bridge()->GetStorageKey(SpecificsToEntity(specifics2)), kCardIdA);
AutofillWalletSpecifics specifics2 =
CreateAutofillWalletSpecificsForCard(kCard1SpecificsId);
EXPECT_EQ(bridge()->GetStorageKey(SpecificsToEntity(specifics2)),
kCard1SpecificsId);
}
TEST_F(AutofillWalletSyncBridgeTest,
GetAllDataForDebugging_ShouldReturnAllData) {
AutofillProfile address1 = CreateServerProfile(kAddr1ServerId);
AutofillProfile address2 = CreateServerProfile(kAddr2ServerId);
table()->SetServerProfiles({address1, address2});
CreditCard card1 = CreateServerCreditCard(kCard1ServerId);
CreditCard card2 = CreateServerCreditCard(kCard2ServerId);
table()->SetServerCreditCards({card1, card2});
AutofillWalletSpecifics address_specifics1;
SetAutofillWalletSpecificsFromServerProfile(address1, &address_specifics1);
AutofillWalletSpecifics address_specifics2;
SetAutofillWalletSpecificsFromServerProfile(address2, &address_specifics2);
AutofillWalletSpecifics card_specifics1;
SetAutofillWalletSpecificsFromServerCard(card1, &card_specifics1);
AutofillWalletSpecifics card_specifics2;
SetAutofillWalletSpecificsFromServerCard(card2, &card_specifics2);
EXPECT_THAT(GetAllLocalData(),
UnorderedElementsAre(EqualsSpecifics(address_specifics1),
EqualsSpecifics(address_specifics2),
EqualsSpecifics(card_specifics1),
EqualsSpecifics(card_specifics2)));
}
} // namespace autofill
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment