blob: f3d20018958255054470077e3825291da862c026 [file] [log] [blame]
// Copyright 2017 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 "ios/chrome/browser/payments/payment_request.h"
#include <memory>
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/scoped_task_environment.h"
#include "components/autofill/core/browser/autofill_test_utils.h"
#include "components/autofill/core/browser/autofill_type.h"
#include "components/autofill/core/browser/field_types.h"
#include "components/autofill/core/browser/test_personal_data_manager.h"
#include "components/payments/core/autofill_payment_instrument.h"
#include "components/payments/core/currency_formatter.h"
#include "components/payments/core/features.h"
#include "components/payments/core/payment_details.h"
#include "components/payments/core/payment_method_data.h"
#include "components/payments/core/payment_options.h"
#include "components/payments/core/payment_shipping_option.h"
#include "components/payments/core/payments_profile_comparator.h"
#include "components/payments/core/web_payment_request.h"
#include "ios/chrome/browser/application_context.h"
#include "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
#include "ios/chrome/browser/payments/payment_request_test_util.h"
#include "ios/chrome/browser/payments/test_payment_request.h"
#import "ios/web/public/test/fakes/test_web_state.h"
#include "testing/gmock/include/gmock/gmock-matchers.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace {
using ::testing::_;
class MockTestPersonalDataManager : public autofill::TestPersonalDataManager {
public:
MockTestPersonalDataManager() : TestPersonalDataManager() {
SetAutofillProfileEnabled(true);
SetAutofillCreditCardEnabled(true);
SetAutofillWalletImportEnabled(true);
}
MOCK_METHOD1(RecordUseOf, void(const autofill::AutofillDataModel&));
MOCK_METHOD1(UpdateCreditCard, void(const autofill::CreditCard&));
MOCK_METHOD1(UpdateServerCardMetadata, void(const autofill::CreditCard&));
MOCK_METHOD1(UpdateProfile, void(const autofill::AutofillProfile&));
};
class MockPaymentsProfileComparator
: public payments::PaymentsProfileComparator {
public:
MockPaymentsProfileComparator(const std::string& app_locale,
const payments::PaymentOptionsProvider& options)
: PaymentsProfileComparator(app_locale, options) {}
MOCK_METHOD1(Invalidate, void(const autofill::AutofillProfile&));
};
MATCHER_P(GuidMatches, guid, "") {
return arg.guid() == guid;
}
} // namespace
namespace payments {
class PaymentRequestTest : public PlatformTest {
protected:
PaymentRequestTest()
: chrome_browser_state_(TestChromeBrowserState::Builder().Build()) {
test_personal_data_manager_.SetAutofillProfileEnabled(true);
test_personal_data_manager_.SetAutofillCreditCardEnabled(true);
test_personal_data_manager_.SetAutofillWalletImportEnabled(true);
}
// Returns PaymentDetails with one shipping option that's selected.
PaymentDetails CreateDetailsWithShippingOption() {
PaymentDetails details;
std::vector<PaymentShippingOption> shipping_options;
PaymentShippingOption option1;
option1.id = "option:1";
option1.selected = true;
shipping_options.push_back(std::move(option1));
details.shipping_options = std::move(shipping_options);
return details;
}
PaymentOptions CreatePaymentOptions(bool request_payer_name,
bool request_payer_phone,
bool request_payer_email,
bool request_shipping) {
PaymentOptions options;
options.request_payer_name = request_payer_name;
options.request_payer_phone = request_payer_phone;
options.request_payer_email = request_payer_email;
options.request_shipping = request_shipping;
return options;
}
base::test::ScopedTaskEnvironment scoped_task_environment_;
autofill::TestPersonalDataManager test_personal_data_manager_;
web::TestWebState web_state_;
std::unique_ptr<TestChromeBrowserState> chrome_browser_state_;
};
// Tests that the CurrencyFormatter is constructed with the correct
// currency code and currency system.
TEST_F(PaymentRequestTest, CreatesCurrencyFormatterCorrectly) {
WebPaymentRequest web_payment_request;
web_payment_request.details.total = std::make_unique<PaymentItem>();
web_payment_request.details.total->amount->currency = "USD";
TestPaymentRequest payment_request1(web_payment_request,
chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
ASSERT_EQ("en", payment_request1.GetApplicationLocale());
CurrencyFormatter* currency_formatter =
payment_request1.GetOrCreateCurrencyFormatter();
EXPECT_EQ(base::UTF8ToUTF16("$55.00"), currency_formatter->Format("55.00"));
EXPECT_EQ("USD", currency_formatter->formatted_currency_code());
web_payment_request.details.total->amount->currency = "JPY";
TestPaymentRequest payment_request2(web_payment_request,
chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
ASSERT_EQ("en", payment_request2.GetApplicationLocale());
currency_formatter = payment_request2.GetOrCreateCurrencyFormatter();
EXPECT_EQ(base::UTF8ToUTF16("¥55"), currency_formatter->Format("55.00"));
EXPECT_EQ("JPY", currency_formatter->formatted_currency_code());
}
// Tests that the accepted card networks are identified correctly.
TEST_F(PaymentRequestTest, AcceptedPaymentNetworks) {
WebPaymentRequest web_payment_request;
PaymentMethodData method_datum1;
method_datum1.supported_method = "visa";
web_payment_request.method_data.push_back(method_datum1);
PaymentMethodData method_datum2;
method_datum2.supported_method = "mastercard";
web_payment_request.method_data.push_back(method_datum2);
TestPaymentRequest payment_request(web_payment_request,
chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
ASSERT_EQ(2U, payment_request.supported_card_networks().size());
EXPECT_EQ("visa", payment_request.supported_card_networks()[0]);
EXPECT_EQ("mastercard", payment_request.supported_card_networks()[1]);
}
// Test that parsing supported methods (with invalid values and duplicates)
// works as expected.
TEST_F(PaymentRequestTest, SupportedMethods) {
WebPaymentRequest web_payment_request;
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(features::kWebPaymentsNativeApps);
PaymentMethodData method_datum1;
method_datum1.supported_method = "visa";
PaymentMethodData method_datum2;
method_datum2.supported_method = "mastercard";
PaymentMethodData method_datum3;
method_datum3.supported_method = "invalid";
PaymentMethodData method_datum4;
method_datum4.supported_method = "visa";
PaymentMethodData method_datum5;
method_datum5.supported_method = "https://bobpay.com";
PaymentMethodData method_datum6;
method_datum6.supported_method = "http://invalidpay.com";
web_payment_request.method_data.push_back(method_datum1);
web_payment_request.method_data.push_back(method_datum2);
web_payment_request.method_data.push_back(method_datum3);
web_payment_request.method_data.push_back(method_datum4);
web_payment_request.method_data.push_back(method_datum5);
web_payment_request.method_data.push_back(method_datum6);
TestPaymentRequest payment_request(web_payment_request,
chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
payment_request.ResetParsedPaymentMethodData();
ASSERT_EQ(2U, payment_request.supported_card_networks().size());
EXPECT_EQ("visa", payment_request.supported_card_networks()[0]);
EXPECT_EQ("mastercard", payment_request.supported_card_networks()[1]);
ASSERT_EQ(1U, payment_request.url_payment_method_identifiers().size());
EXPECT_EQ(GURL("https://bobpay.com"),
payment_request.url_payment_method_identifiers()[0]);
}
// Test that parsing supported methods in different method data entries (with
// invalid values and duplicates) works as expected.
TEST_F(PaymentRequestTest, SupportedMethods_MultipleEntries) {
WebPaymentRequest web_payment_request;
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(features::kWebPaymentsNativeApps);
PaymentMethodData method_datum1;
method_datum1.supported_method = "visa";
PaymentMethodData method_datum2;
method_datum2.supported_method = "https://bobpay.com";
PaymentMethodData method_datum3;
method_datum3.supported_method = "mastercard";
PaymentMethodData method_datum4;
method_datum4.supported_method = "http://invalidpay.com";
PaymentMethodData method_datum5;
method_datum5.supported_method = "visa";
PaymentMethodData method_datum6;
method_datum6.supported_method = "https://bobpay.com";
web_payment_request.method_data.push_back(method_datum1);
web_payment_request.method_data.push_back(method_datum2);
web_payment_request.method_data.push_back(method_datum3);
web_payment_request.method_data.push_back(method_datum4);
web_payment_request.method_data.push_back(method_datum5);
web_payment_request.method_data.push_back(method_datum6);
TestPaymentRequest payment_request(web_payment_request,
chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
payment_request.ResetParsedPaymentMethodData();
ASSERT_EQ(2U, payment_request.supported_card_networks().size());
EXPECT_EQ("visa", payment_request.supported_card_networks()[0]);
EXPECT_EQ("mastercard", payment_request.supported_card_networks()[1]);
ASSERT_EQ(1U, payment_request.url_payment_method_identifiers().size());
EXPECT_EQ(GURL("https://bobpay.com"),
payment_request.url_payment_method_identifiers()[0]);
}
// Test that only specifying basic-card means that all are supported.
TEST_F(PaymentRequestTest, SupportedMethods_OnlyBasicCard) {
WebPaymentRequest web_payment_request;
PaymentMethodData method_datum1;
method_datum1.supported_method = "basic-card";
web_payment_request.method_data.push_back(method_datum1);
TestPaymentRequest payment_request(web_payment_request,
chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
// All of the basic card networks are supported.
ASSERT_EQ(8U, payment_request.supported_card_networks().size());
EXPECT_EQ("amex", payment_request.supported_card_networks()[0]);
EXPECT_EQ("diners", payment_request.supported_card_networks()[1]);
EXPECT_EQ("discover", payment_request.supported_card_networks()[2]);
EXPECT_EQ("jcb", payment_request.supported_card_networks()[3]);
EXPECT_EQ("mastercard", payment_request.supported_card_networks()[4]);
EXPECT_EQ("mir", payment_request.supported_card_networks()[5]);
EXPECT_EQ("unionpay", payment_request.supported_card_networks()[6]);
EXPECT_EQ("visa", payment_request.supported_card_networks()[7]);
EXPECT_TRUE(payment_request.url_payment_method_identifiers().empty());
}
// Test that specifying a method AND basic-card means that all are supported,
// but with the method as first.
TEST_F(PaymentRequestTest, SupportedMethods_BasicCard_WithSpecificMethod) {
WebPaymentRequest web_payment_request;
PaymentMethodData method_datum1;
method_datum1.supported_method = "jcb";
PaymentMethodData method_datum2;
method_datum2.supported_method = "basic-card";
web_payment_request.method_data.push_back(method_datum1);
web_payment_request.method_data.push_back(method_datum2);
TestPaymentRequest payment_request(web_payment_request,
chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
// All of the basic card networks are supported, but JCB is first because it
// was specified first.
EXPECT_EQ(8u, payment_request.supported_card_networks().size());
EXPECT_EQ("jcb", payment_request.supported_card_networks()[0]);
EXPECT_EQ("amex", payment_request.supported_card_networks()[1]);
EXPECT_EQ("diners", payment_request.supported_card_networks()[2]);
EXPECT_EQ("discover", payment_request.supported_card_networks()[3]);
EXPECT_EQ("mastercard", payment_request.supported_card_networks()[4]);
EXPECT_EQ("mir", payment_request.supported_card_networks()[5]);
EXPECT_EQ("unionpay", payment_request.supported_card_networks()[6]);
EXPECT_EQ("visa", payment_request.supported_card_networks()[7]);
}
// Test that specifying basic-card with a supported network (with previous
// supported methods) will work as expected
TEST_F(PaymentRequestTest, SupportedMethods_BasicCard_Overlap) {
WebPaymentRequest web_payment_request;
PaymentMethodData method_datum1;
method_datum1.supported_method = "mastercard";
PaymentMethodData method_datum2;
method_datum2.supported_method = "visa";
PaymentMethodData method_datum3;
method_datum3.supported_method = "basic-card";
method_datum3.supported_networks.push_back("visa");
method_datum3.supported_networks.push_back("mastercard");
method_datum3.supported_networks.push_back("unionpay");
web_payment_request.method_data.push_back(method_datum1);
web_payment_request.method_data.push_back(method_datum2);
web_payment_request.method_data.push_back(method_datum3);
TestPaymentRequest payment_request(web_payment_request,
chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
EXPECT_EQ(3u, payment_request.supported_card_networks().size());
EXPECT_EQ("mastercard", payment_request.supported_card_networks()[0]);
EXPECT_EQ("visa", payment_request.supported_card_networks()[1]);
EXPECT_EQ("unionpay", payment_request.supported_card_networks()[2]);
}
// Test that specifying basic-card with supported networks after specifying
// some methods
TEST_F(PaymentRequestTest, SupportedMethods_BasicCard_WithSupportedNetworks) {
WebPaymentRequest web_payment_request;
PaymentMethodData method_datum1;
method_datum1.supported_method = "basic-card";
method_datum1.supported_networks.push_back("visa");
method_datum1.supported_networks.push_back("unionpay");
web_payment_request.method_data.push_back(method_datum1);
TestPaymentRequest payment_request(web_payment_request,
chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
// Only the specified networks are supported.
EXPECT_EQ(2u, payment_request.supported_card_networks().size());
EXPECT_EQ("visa", payment_request.supported_card_networks()[0]);
EXPECT_EQ("unionpay", payment_request.supported_card_networks()[1]);
}
TEST_F(PaymentRequestTest, GooglePayCardsInBasicCard_Allowed) {
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(features::kReturnGooglePayInBasicCard);
WebPaymentRequest web_payment_request;
PaymentMethodData method_datum;
method_datum.supported_method = "basic-card";
method_datum.supported_networks.push_back("mastercard");
web_payment_request.method_data.push_back(method_datum);
// Add a mastercard with billing address.
autofill::AutofillProfile address = autofill::test::GetFullProfile();
test_personal_data_manager_.AddProfile(address);
autofill::CreditCard credit_card = autofill::test::GetMaskedServerCard();
credit_card.set_card_type(autofill::CreditCard::CardType::CARD_TYPE_CREDIT);
credit_card.set_billing_address_id(address.guid());
test_personal_data_manager_.AddServerCreditCard(credit_card);
TestPaymentRequest payment_request(web_payment_request,
chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
// The card is available in the payment request, and added to the
// PersonalDataManager.
EXPECT_EQ(1U, payment_request.payment_methods().size());
// The card is expected to have been added to the PersonalDataManager.
EXPECT_EQ(1U, test_personal_data_manager_.GetCreditCards().size());
}
TEST_F(PaymentRequestTest, GooglePayCardsInBasicCard_NotAllowed) {
base::test::ScopedFeatureList feature_list;
feature_list.InitAndDisableFeature(features::kReturnGooglePayInBasicCard);
WebPaymentRequest web_payment_request;
PaymentMethodData method_datum;
method_datum.supported_method = "basic-card";
method_datum.supported_networks.push_back("mastercard");
web_payment_request.method_data.push_back(method_datum);
// Add a mastercard with billing address.
autofill::AutofillProfile address = autofill::test::GetFullProfile();
test_personal_data_manager_.AddProfile(address);
autofill::CreditCard credit_card = autofill::test::GetMaskedServerCard();
credit_card.set_card_type(autofill::CreditCard::CardType::CARD_TYPE_CREDIT);
credit_card.set_billing_address_id(address.guid());
test_personal_data_manager_.AddServerCreditCard(credit_card);
TestPaymentRequest payment_request(web_payment_request,
chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
// The card is not available in the payment request, but added to the
// PersonalDataManager.
EXPECT_TRUE(payment_request.payment_methods().empty());
// The card is expected to have been added to the PersonalDataManager.
EXPECT_EQ(1U, test_personal_data_manager_.GetCreditCards().size());
}
// Tests that an autofill payment instrumnt e.g., credit cards can be added
// to the list of available payment methods.
TEST_F(PaymentRequestTest, CreateAndAddAutofillPaymentInstrument) {
WebPaymentRequest web_payment_request;
PaymentMethodData method_datum;
method_datum.supported_method = "basic-card";
method_datum.supported_networks.push_back("visa");
web_payment_request.method_data.push_back(method_datum);
TestPaymentRequest payment_request(web_payment_request,
chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
EXPECT_EQ(0U, payment_request.payment_methods().size());
autofill::CreditCard credit_card_1 = autofill::test::GetCreditCard();
AutofillPaymentInstrument* added_credit_card_1 =
payment_request.CreateAndAddAutofillPaymentInstrument(credit_card_1);
EXPECT_EQ(credit_card_1, *added_credit_card_1->credit_card());
EXPECT_EQ(1U, payment_request.payment_methods().size());
// The card is expected to have been added to the PersonalDataManager.
EXPECT_EQ(1U, test_personal_data_manager_.GetCreditCards().size());
}
// Tests that an autofill payment instrumnt e.g., credit cards can be added
// to the list of available payment methods in incognito mode.
TEST_F(PaymentRequestTest, CreateAndAddAutofillPaymentInstrumentIncognito) {
WebPaymentRequest web_payment_request;
PaymentMethodData method_datum;
method_datum.supported_method = "basic-card";
method_datum.supported_networks.push_back("visa");
web_payment_request.method_data.push_back(method_datum);
TestPaymentRequest payment_request(web_payment_request,
chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
EXPECT_EQ(0U, payment_request.payment_methods().size());
payment_request.set_is_incognito(true);
autofill::CreditCard credit_card_1 = autofill::test::GetCreditCard();
AutofillPaymentInstrument* added_credit_card_1 =
payment_request.CreateAndAddAutofillPaymentInstrument(credit_card_1);
EXPECT_EQ(credit_card_1, *added_credit_card_1->credit_card());
EXPECT_EQ(1U, payment_request.payment_methods().size());
// The card should not get added to the PersonalDataManager.
EXPECT_EQ(0U, test_personal_data_manager_.GetCreditCards().size());
}
// Tests updating local and server autofill payment instruments.
TEST_F(PaymentRequestTest, UpdateAutofillPaymentInstrument) {
WebPaymentRequest web_payment_request;
PaymentMethodData method_datum;
method_datum.supported_method = "basic-card";
method_datum.supported_networks.push_back("visa");
method_datum.supported_networks.push_back("amex");
web_payment_request.method_data.push_back(method_datum);
MockTestPersonalDataManager personal_data_manager;
TestPaymentRequest payment_request(web_payment_request,
chrome_browser_state_.get(), &web_state_,
&personal_data_manager);
// Credit card should get updated in Personal Data Manager.
EXPECT_CALL(personal_data_manager, UpdateCreditCard(_)).Times(1);
autofill::CreditCard credit_card_1 = autofill::test::GetCreditCard();
payment_request.UpdateAutofillPaymentInstrument(credit_card_1);
// Only credit card's meta data should get updated in PersonalDataManager.
EXPECT_CALL(personal_data_manager, UpdateServerCardMetadata(_)).Times(1);
autofill::CreditCard credit_card_2 =
autofill::test::GetMaskedServerCardAmex();
payment_request.UpdateAutofillPaymentInstrument(credit_card_2);
}
// Tests updating local and server autofill payment instruments in incognito
// mode.
TEST_F(PaymentRequestTest, UpdateAutofillPaymentInstrumentIncognito) {
WebPaymentRequest web_payment_request;
PaymentMethodData method_datum;
method_datum.supported_method = "basic-card";
method_datum.supported_networks.push_back("visa");
method_datum.supported_networks.push_back("amex");
web_payment_request.method_data.push_back(method_datum);
MockTestPersonalDataManager personal_data_manager;
TestPaymentRequest payment_request(web_payment_request,
chrome_browser_state_.get(), &web_state_,
&personal_data_manager);
payment_request.set_is_incognito(true);
// Credit card should not get updated in Personal Data Manager.
EXPECT_CALL(personal_data_manager, UpdateCreditCard(_)).Times(0);
autofill::CreditCard credit_card_1 = autofill::test::GetCreditCard();
payment_request.UpdateAutofillPaymentInstrument(credit_card_1);
// Only credit card's meta data should not get updated in PersonalDataManager.
EXPECT_CALL(personal_data_manager, UpdateServerCardMetadata(_)).Times(0);
autofill::CreditCard credit_card_2 =
autofill::test::GetMaskedServerCardAmex();
payment_request.UpdateAutofillPaymentInstrument(credit_card_2);
}
// Tests that a profile can be added to the list of available profiles.
TEST_F(PaymentRequestTest, AddAutofillProfile) {
WebPaymentRequest web_payment_request;
web_payment_request.options = CreatePaymentOptions(
/*request_payer_name=*/true, /*request_payer_phone=*/true,
/*request_payer_email=*/true, /*request_shipping=*/true);
TestPaymentRequest payment_request(web_payment_request,
chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
EXPECT_EQ(0U, payment_request.shipping_profiles().size());
EXPECT_EQ(0U, payment_request.contact_profiles().size());
autofill::AutofillProfile profile_1 = autofill::test::GetFullProfile();
autofill::AutofillProfile* added_profile_1 =
payment_request.AddAutofillProfile(profile_1);
EXPECT_EQ(profile_1, *added_profile_1);
EXPECT_EQ(1U, payment_request.shipping_profiles().size());
EXPECT_EQ(1U, payment_request.contact_profiles().size());
// The autofill profile should have been added to the PersonalDataManager.
EXPECT_EQ(1U, test_personal_data_manager_.GetProfiles().size());
}
// Tests that a profile can be added to the list of available profiles in
// incognito mode.
TEST_F(PaymentRequestTest, AddAutofillProfileIncognito) {
WebPaymentRequest web_payment_request;
web_payment_request.options = CreatePaymentOptions(
/*request_payer_name=*/true, /*request_payer_phone=*/true,
/*request_payer_email=*/true, /*request_shipping=*/true);
TestPaymentRequest payment_request(web_payment_request,
chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
EXPECT_EQ(0U, payment_request.shipping_profiles().size());
EXPECT_EQ(0U, payment_request.contact_profiles().size());
payment_request.set_is_incognito(true);
autofill::AutofillProfile profile_1 = autofill::test::GetFullProfile();
autofill::AutofillProfile* added_profile_1 =
payment_request.AddAutofillProfile(profile_1);
EXPECT_EQ(profile_1, *added_profile_1);
EXPECT_EQ(1U, payment_request.shipping_profiles().size());
EXPECT_EQ(1U, payment_request.contact_profiles().size());
// The autofill profile should not get added to the PersonalDataManager.
EXPECT_EQ(0U, test_personal_data_manager_.GetProfiles().size());
}
// Tests updating an autofill profile.
TEST_F(PaymentRequestTest, UpdateAutofillProfile) {
WebPaymentRequest web_payment_request;
web_payment_request.options = CreatePaymentOptions(
/*request_payer_name=*/true, /*request_payer_phone=*/true,
/*request_payer_email=*/true, /*request_shipping=*/true);
MockTestPersonalDataManager personal_data_manager;
TestPaymentRequest payment_request(web_payment_request,
chrome_browser_state_.get(), &web_state_,
&personal_data_manager);
MockPaymentsProfileComparator profile_comparator(
payment_request.GetApplicationLocale(), payment_request);
payment_request.SetProfileComparator(&profile_comparator);
// Profile should get updated in PersonalDataManager.
EXPECT_CALL(personal_data_manager, UpdateProfile(_)).Times(1);
EXPECT_CALL(profile_comparator, Invalidate(_)).Times(1);
autofill::AutofillProfile profile = autofill::test::GetFullProfile();
payment_request.UpdateAutofillProfile(profile);
}
// Tests updating an autofill profile in incognito mode.
TEST_F(PaymentRequestTest, UpdateAutofillProfileIncognito) {
WebPaymentRequest web_payment_request;
web_payment_request.options = CreatePaymentOptions(
/*request_payer_name=*/true, /*request_payer_phone=*/true,
/*request_payer_email=*/true, /*request_shipping=*/true);
MockTestPersonalDataManager personal_data_manager;
TestPaymentRequest payment_request(web_payment_request,
chrome_browser_state_.get(), &web_state_,
&personal_data_manager);
payment_request.set_is_incognito(true);
MockPaymentsProfileComparator profile_comparator(
payment_request.GetApplicationLocale(), payment_request);
payment_request.SetProfileComparator(&profile_comparator);
// Profile should not get updated in PersonalDataManager.
EXPECT_CALL(personal_data_manager, UpdateProfile(_)).Times(0);
EXPECT_CALL(profile_comparator, Invalidate(_)).Times(1);
autofill::AutofillProfile profile = autofill::test::GetFullProfile();
payment_request.UpdateAutofillProfile(profile);
}
// Test that parsing shipping options works as expected.
TEST_F(PaymentRequestTest, SelectedShippingOptions) {
WebPaymentRequest web_payment_request;
PaymentDetails details;
details.total = std::make_unique<PaymentItem>();
std::vector<PaymentShippingOption> shipping_options;
PaymentShippingOption option1;
option1.id = "option:1";
option1.selected = false;
shipping_options.push_back(std::move(option1));
PaymentShippingOption option2;
option2.id = "option:2";
option2.selected = true;
shipping_options.push_back(std::move(option2));
PaymentShippingOption option3;
option3.id = "option:3";
option3.selected = true;
shipping_options.push_back(std::move(option3));
details.shipping_options = std::move(shipping_options);
web_payment_request.details = std::move(details);
TestPaymentRequest payment_request(web_payment_request,
chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
// The last one marked "selected" should be selected.
EXPECT_EQ("option:3", payment_request.selected_shipping_option()->id);
// Simulate an update that no longer has any shipping options. There is no
// longer a selected shipping option.
PaymentDetails new_details;
payment_request.UpdatePaymentDetails(std::move(new_details));
EXPECT_EQ(nullptr, payment_request.selected_shipping_option());
}
// Tests that updating the payment details updates the total amount.
TEST_F(PaymentRequestTest, UpdatePaymentDetailsNewTotal) {
WebPaymentRequest web_payment_request;
PaymentDetails details;
details.total = std::make_unique<PaymentItem>();
details.total->amount->value = "10.00";
details.total->amount->currency = "USD";
web_payment_request.details = std::move(details);
TestPaymentRequest payment_request(web_payment_request,
chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
// Simulate an update with a new total amount.
PaymentDetails new_details;
new_details.total = std::make_unique<PaymentItem>();
new_details.total->amount->value = "20.00";
new_details.total->amount->currency = "CAD";
payment_request.UpdatePaymentDetails(std::move(new_details));
EXPECT_EQ("20.00", payment_request.payment_details().total->amount->value);
EXPECT_EQ("CAD", payment_request.payment_details().total->amount->currency);
}
// Tests that updating the payment details with a PaymentDetails instance that
// is missing the total amount, maintains the old total amount.
TEST_F(PaymentRequestTest, UpdatePaymentDetailsNoTotal) {
WebPaymentRequest web_payment_request;
PaymentDetails details;
details.total = std::make_unique<PaymentItem>();
details.total->amount->value = "10.00";
details.total->amount->currency = "USD";
web_payment_request.details = std::move(details);
TestPaymentRequest payment_request(web_payment_request,
chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
// Simulate an update with the total amount missing.
PaymentDetails new_details;
payment_request.UpdatePaymentDetails(std::move(new_details));
EXPECT_EQ("10.00", payment_request.payment_details().total->amount->value);
EXPECT_EQ("USD", payment_request.payment_details().total->amount->currency);
}
// Test that loading profiles when none are available works as expected.
TEST_F(PaymentRequestTest, SelectedProfiles_NoProfiles) {
WebPaymentRequest web_payment_request;
web_payment_request.details = CreateDetailsWithShippingOption();
web_payment_request.options = CreatePaymentOptions(
/*request_payer_name=*/true, /*request_payer_phone=*/true,
/*request_payer_email=*/true, /*request_shipping=*/true);
// No profiles are selected because none are available!
TestPaymentRequest payment_request(web_payment_request,
chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
EXPECT_EQ(nullptr, payment_request.selected_shipping_profile());
EXPECT_EQ(nullptr, payment_request.selected_contact_profile());
}
// Test that loading complete shipping and contact profiles works as expected.
TEST_F(PaymentRequestTest, SelectedProfiles_Complete) {
autofill::AutofillProfile address = autofill::test::GetFullProfile();
address.set_use_count(5U);
test_personal_data_manager_.AddProfile(address);
autofill::AutofillProfile address2 = autofill::test::GetFullProfile2();
address2.set_use_count(15U);
test_personal_data_manager_.AddProfile(address2);
WebPaymentRequest web_payment_request;
web_payment_request.details = CreateDetailsWithShippingOption();
web_payment_request.options = CreatePaymentOptions(
/*request_payer_name=*/true, /*request_payer_phone=*/true,
/*request_payer_email=*/true, /*request_shipping=*/true);
// address2 is selected because it has the most use count (Frecency model).
TestPaymentRequest payment_request(web_payment_request,
chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
EXPECT_EQ(address2.guid(),
payment_request.selected_shipping_profile()->guid());
EXPECT_EQ(address2.guid(),
payment_request.selected_contact_profile()->guid());
}
// Test that loading complete shipping and contact profiles, when there are no
// shipping options available, works as expected.
TEST_F(PaymentRequestTest, SelectedProfiles_Complete_NoShippingOption) {
autofill::AutofillProfile address = autofill::test::GetFullProfile();
address.set_use_count(5U);
test_personal_data_manager_.AddProfile(address);
WebPaymentRequest web_payment_request;
// No shipping options.
web_payment_request.details = PaymentDetails();
web_payment_request.options = CreatePaymentOptions(
/*request_payer_name=*/true, /*request_payer_phone=*/true,
/*request_payer_email=*/true, /*request_shipping=*/true);
// No shipping profile is selected because the merchant has not selected a
// shipping option. However there is a suitable contact profile.
TestPaymentRequest payment_request(web_payment_request,
chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
EXPECT_EQ(nullptr, payment_request.selected_shipping_profile());
EXPECT_EQ(address.guid(), payment_request.selected_contact_profile()->guid());
}
// Test that loading incomplete shipping and contact profiles works as expected.
TEST_F(PaymentRequestTest, SelectedProfiles_Incomplete) {
// Add a profile with no phone (incomplete).
autofill::AutofillProfile address1 = autofill::test::GetFullProfile();
address1.SetInfo(autofill::AutofillType(autofill::PHONE_HOME_WHOLE_NUMBER),
base::string16(), "en-US");
address1.set_use_count(5U);
test_personal_data_manager_.AddProfile(address1);
// Add a complete profile, with fewer use counts.
autofill::AutofillProfile address2 = autofill::test::GetFullProfile2();
address2.set_use_count(3U);
test_personal_data_manager_.AddProfile(address2);
WebPaymentRequest web_payment_request;
web_payment_request.details = CreateDetailsWithShippingOption();
web_payment_request.options = CreatePaymentOptions(
/*request_payer_name=*/true, /*request_payer_phone=*/true,
/*request_payer_email=*/true, /*request_shipping=*/true);
// Even though address1 has more use counts, address2 is selected because it
// is complete.
TestPaymentRequest payment_request(web_payment_request,
chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
EXPECT_EQ(address2.guid(),
payment_request.selected_shipping_profile()->guid());
EXPECT_EQ(address2.guid(),
payment_request.selected_contact_profile()->guid());
}
// Test that loading incomplete contact profiles works as expected when the
// merchant is not interested in the missing field. Test that the most complete
// shipping profile is selected.
TEST_F(PaymentRequestTest,
SelectedProfiles_IncompleteContact_NoRequestPayerPhone) {
// Add a profile with no phone (incomplete).
autofill::AutofillProfile address1 = autofill::test::GetFullProfile();
address1.SetInfo(autofill::AutofillType(autofill::PHONE_HOME_WHOLE_NUMBER),
base::string16(), "en-US");
address1.set_use_count(5U);
test_personal_data_manager_.AddProfile(address1);
// Add a complete profile, with fewer use counts.
autofill::AutofillProfile address2 = autofill::test::GetFullProfile();
address2.set_use_count(3U);
test_personal_data_manager_.AddProfile(address2);
WebPaymentRequest web_payment_request;
web_payment_request.details = CreateDetailsWithShippingOption();
// The merchant doesn't care about the phone number.
web_payment_request.options = CreatePaymentOptions(
/*request_payer_name=*/true, /*request_payer_phone=*/false,
/*request_payer_email=*/true, /*request_shipping=*/true);
// address1 has more use counts, and even though it has no phone number, it's
// still selected as the contact profile because merchant doesn't require
// phone. address2 is selected as the shipping profile because it's the most
// complete for shipping.
TestPaymentRequest payment_request(web_payment_request,
chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
EXPECT_EQ(address2.guid(),
payment_request.selected_shipping_profile()->guid());
EXPECT_EQ(address1.guid(),
payment_request.selected_contact_profile()->guid());
}
// Test that loading payment methods when none are available works as expected.
TEST_F(PaymentRequestTest, SelectedPaymentMethod_NoPaymentMethods) {
WebPaymentRequest web_payment_request =
payment_request_test_util::CreateTestWebPaymentRequest();
// No payment methods are selected because none are available!
TestPaymentRequest payment_request(web_payment_request,
chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
EXPECT_EQ(nullptr, payment_request.selected_payment_method());
}
// Test that loading expired credit cards works as expected.
TEST_F(PaymentRequestTest, SelectedPaymentMethod_ExpiredCard) {
autofill::AutofillProfile billing_address = autofill::test::GetFullProfile();
test_personal_data_manager_.AddProfile(billing_address);
autofill::CreditCard credit_card = autofill::test::GetCreditCard();
credit_card.SetExpirationYear(2016); // Expired.
credit_card.set_billing_address_id(billing_address.guid());
test_personal_data_manager_.AddCreditCard(credit_card);
WebPaymentRequest web_payment_request =
payment_request_test_util::CreateTestWebPaymentRequest();
// credit_card is selected because expired cards are valid for payment.
TestPaymentRequest payment_request(web_payment_request,
chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
EXPECT_EQ(payment_request.selected_payment_method()->type(),
PaymentInstrument::Type::AUTOFILL);
AutofillPaymentInstrument* payment_instrument =
static_cast<AutofillPaymentInstrument*>(
payment_request.selected_payment_method());
EXPECT_EQ(credit_card.guid(), payment_instrument->credit_card()->guid());
}
// Test that loading complete payment methods works as expected.
TEST_F(PaymentRequestTest, SelectedPaymentMethod_Complete) {
autofill::AutofillProfile billing_address = autofill::test::GetFullProfile();
test_personal_data_manager_.AddProfile(billing_address);
autofill::CreditCard credit_card = autofill::test::GetCreditCard();
credit_card.set_use_count(5U);
credit_card.set_billing_address_id(billing_address.guid());
test_personal_data_manager_.AddCreditCard(credit_card);
autofill::CreditCard credit_card2 = autofill::test::GetCreditCard2();
credit_card2.set_use_count(15U);
credit_card2.set_billing_address_id(billing_address.guid());
test_personal_data_manager_.AddCreditCard(credit_card2);
WebPaymentRequest web_payment_request =
payment_request_test_util::CreateTestWebPaymentRequest();
// credit_card2 is selected because it has the most use count (Frecency
// model).
TestPaymentRequest payment_request(web_payment_request,
chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
AutofillPaymentInstrument* payment_instrument =
static_cast<AutofillPaymentInstrument*>(
payment_request.selected_payment_method());
EXPECT_EQ(credit_card2.guid(), payment_instrument->credit_card()->guid());
}
// Test that loading incomplete payment methods works as expected.
TEST_F(PaymentRequestTest, SelectedPaymentMethod_Incomplete) {
autofill::AutofillProfile billing_address = autofill::test::GetFullProfile();
test_personal_data_manager_.AddProfile(billing_address);
autofill::CreditCard credit_card = autofill::test::GetCreditCard();
credit_card.set_use_count(5U);
credit_card.set_billing_address_id(billing_address.guid());
test_personal_data_manager_.AddCreditCard(credit_card);
autofill::CreditCard credit_card2 = autofill::test::GetCreditCard2();
credit_card2.set_use_count(15U);
test_personal_data_manager_.AddCreditCard(credit_card2);
WebPaymentRequest web_payment_request =
payment_request_test_util::CreateTestWebPaymentRequest();
// Even though credit_card2 has more use counts, credit_card is selected
// because it is complete.
TestPaymentRequest payment_request(web_payment_request,
chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
AutofillPaymentInstrument* payment_instrument =
static_cast<AutofillPaymentInstrument*>(
payment_request.selected_payment_method());
EXPECT_EQ(credit_card.guid(), payment_instrument->credit_card()->guid());
}
// Test that the use counts of the data models are updated as expected when
// different autofill profiles are used as the shipping address and the contact
// info.
TEST_F(PaymentRequestTest, RecordUseStats_RequestShippingAndContactInfo) {
MockTestPersonalDataManager personal_data_manager;
// Add a profile that is incomplete for a contact info, but is used more
// frequently so is selected as the default shipping address.
autofill::AutofillProfile address = autofill::test::GetFullProfile();
address.SetInfo(autofill::AutofillType(autofill::EMAIL_ADDRESS),
base::string16(), "en-US");
address.set_use_count(10U);
personal_data_manager.AddProfile(address);
autofill::AutofillProfile contact_info = autofill::test::GetFullProfile2();
contact_info.set_use_count(5U);
personal_data_manager.AddProfile(contact_info);
autofill::CreditCard credit_card = autofill::test::GetCreditCard();
credit_card.set_billing_address_id(address.guid());
personal_data_manager.AddCreditCard(credit_card);
WebPaymentRequest web_payment_request =
payment_request_test_util::CreateTestWebPaymentRequest();
TestPaymentRequest payment_request(web_payment_request,
chrome_browser_state_.get(), &web_state_,
&personal_data_manager);
AutofillPaymentInstrument* payment_instrument =
static_cast<AutofillPaymentInstrument*>(
payment_request.selected_payment_method());
EXPECT_EQ(address.guid(),
payment_request.selected_shipping_profile()->guid());
EXPECT_EQ(contact_info.guid(),
payment_request.selected_contact_profile()->guid());
EXPECT_EQ(credit_card.guid(), payment_instrument->credit_card()->guid());
EXPECT_CALL(personal_data_manager, RecordUseOf(GuidMatches(address.guid())))
.Times(1);
EXPECT_CALL(personal_data_manager,
RecordUseOf(GuidMatches(contact_info.guid())))
.Times(1);
EXPECT_CALL(personal_data_manager,
RecordUseOf(GuidMatches(credit_card.guid())))
.Times(1);
payment_request.RecordUseStats();
}
// Test that the use counts of the data models are updated as expected when the
// same autofill profile is used as the shipping address and the contact info.
TEST_F(PaymentRequestTest, RecordUseStats_SameShippingAndContactInfoProfile) {
MockTestPersonalDataManager personal_data_manager;
autofill::AutofillProfile address = autofill::test::GetFullProfile();
personal_data_manager.AddProfile(address);
autofill::CreditCard credit_card = autofill::test::GetCreditCard();
credit_card.set_billing_address_id(address.guid());
personal_data_manager.AddCreditCard(credit_card);
WebPaymentRequest web_payment_request =
payment_request_test_util::CreateTestWebPaymentRequest();
TestPaymentRequest payment_request(web_payment_request,
chrome_browser_state_.get(), &web_state_,
&personal_data_manager);
AutofillPaymentInstrument* payment_instrument =
static_cast<AutofillPaymentInstrument*>(
payment_request.selected_payment_method());
EXPECT_EQ(address.guid(),
payment_request.selected_shipping_profile()->guid());
EXPECT_EQ(address.guid(), payment_request.selected_contact_profile()->guid());
EXPECT_EQ(credit_card.guid(), payment_instrument->credit_card()->guid());
// Even though |address| is used for contact info, shipping address, and
// credit_card's billing address, the stats should be updated only once.
EXPECT_CALL(personal_data_manager, RecordUseOf(GuidMatches(address.guid())))
.Times(1);
EXPECT_CALL(personal_data_manager,
RecordUseOf(GuidMatches(credit_card.guid())))
.Times(1);
payment_request.RecordUseStats();
}
// Test that the use counts of the data models are updated as expected when no
// contact information is requested.
TEST_F(PaymentRequestTest, RecordUseStats_RequestShippingOnly) {
MockTestPersonalDataManager personal_data_manager;
autofill::AutofillProfile address = autofill::test::GetFullProfile();
personal_data_manager.AddProfile(address);
autofill::CreditCard credit_card = autofill::test::GetCreditCard();
credit_card.set_billing_address_id(address.guid());
personal_data_manager.AddCreditCard(credit_card);
WebPaymentRequest web_payment_request =
payment_request_test_util::CreateTestWebPaymentRequest();
web_payment_request.options.request_payer_name = false;
web_payment_request.options.request_payer_email = false;
web_payment_request.options.request_payer_phone = false;
TestPaymentRequest payment_request(web_payment_request,
chrome_browser_state_.get(), &web_state_,
&personal_data_manager);
AutofillPaymentInstrument* payment_instrument =
static_cast<AutofillPaymentInstrument*>(
payment_request.selected_payment_method());
EXPECT_EQ(address.guid(),
payment_request.selected_shipping_profile()->guid());
EXPECT_EQ(nullptr, payment_request.selected_contact_profile());
EXPECT_EQ(credit_card.guid(), payment_instrument->credit_card()->guid());
EXPECT_CALL(personal_data_manager, RecordUseOf(GuidMatches(address.guid())))
.Times(1);
EXPECT_CALL(personal_data_manager,
RecordUseOf(GuidMatches(credit_card.guid())))
.Times(1);
payment_request.RecordUseStats();
}
// Test that the use counts of the data models are updated as expected when no
// shipping information is requested.
TEST_F(PaymentRequestTest, RecordUseStats_RequestContactInfoOnly) {
MockTestPersonalDataManager personal_data_manager;
autofill::AutofillProfile address = autofill::test::GetFullProfile();
personal_data_manager.AddProfile(address);
autofill::CreditCard credit_card = autofill::test::GetCreditCard();
credit_card.set_billing_address_id(address.guid());
personal_data_manager.AddCreditCard(credit_card);
WebPaymentRequest web_payment_request =
payment_request_test_util::CreateTestWebPaymentRequest();
web_payment_request.options.request_shipping = false;
TestPaymentRequest payment_request(web_payment_request,
chrome_browser_state_.get(), &web_state_,
&personal_data_manager);
AutofillPaymentInstrument* payment_instrument =
static_cast<AutofillPaymentInstrument*>(
payment_request.selected_payment_method());
EXPECT_EQ(nullptr, payment_request.selected_shipping_profile());
EXPECT_EQ(address.guid(), payment_request.selected_contact_profile()->guid());
EXPECT_EQ(credit_card.guid(), payment_instrument->credit_card()->guid());
EXPECT_CALL(personal_data_manager, RecordUseOf(GuidMatches(address.guid())))
.Times(1);
EXPECT_CALL(personal_data_manager,
RecordUseOf(GuidMatches(credit_card.guid())))
.Times(1);
payment_request.RecordUseStats();
}
// Test that the use counts of the data models are updated as expected when no
// shipping or contact information is requested.
TEST_F(PaymentRequestTest, RecordUseStats_NoShippingOrContactInfoRequested) {
MockTestPersonalDataManager personal_data_manager;
autofill::AutofillProfile address = autofill::test::GetFullProfile();
personal_data_manager.AddProfile(address);
autofill::CreditCard credit_card = autofill::test::GetCreditCard();
credit_card.set_billing_address_id(address.guid());
personal_data_manager.AddCreditCard(credit_card);
WebPaymentRequest web_payment_request =
payment_request_test_util::CreateTestWebPaymentRequest();
web_payment_request.options.request_shipping = false;
web_payment_request.options.request_payer_name = false;
web_payment_request.options.request_payer_email = false;
web_payment_request.options.request_payer_phone = false;
TestPaymentRequest payment_request(web_payment_request,
chrome_browser_state_.get(), &web_state_,
&personal_data_manager);
AutofillPaymentInstrument* payment_instrument =
static_cast<AutofillPaymentInstrument*>(
payment_request.selected_payment_method());
EXPECT_EQ(nullptr, payment_request.selected_shipping_profile());
EXPECT_EQ(nullptr, payment_request.selected_contact_profile());
EXPECT_EQ(credit_card.guid(), payment_instrument->credit_card()->guid());
EXPECT_CALL(personal_data_manager, RecordUseOf(GuidMatches(address.guid())))
.Times(0);
EXPECT_CALL(personal_data_manager,
RecordUseOf(GuidMatches(credit_card.guid())))
.Times(1);
payment_request.RecordUseStats();
}
// Tests that the modifier should not get applied when the card network is not
// supported.
TEST_F(PaymentRequestTest, PaymentDetailsModifier_BasicCard_NetworkMismatch) {
autofill::AutofillProfile address = autofill::test::GetFullProfile();
test_personal_data_manager_.AddProfile(address);
autofill::CreditCard credit_card = autofill::test::GetCreditCard(); // Visa.
test_personal_data_manager_.AddCreditCard(credit_card);
credit_card.set_billing_address_id(address.guid());
WebPaymentRequest web_payment_request =
payment_request_test_util::CreateTestWebPaymentRequest();
PaymentDetailsModifier modifier;
modifier.method_data.supported_method = "basic-card";
modifier.method_data.supported_networks.push_back("amex");
modifier.total = std::make_unique<payments::PaymentItem>();
modifier.total->label = "Discounted Total";
modifier.total->amount->value = "0.99";
modifier.total->amount->currency = "USD";
payments::PaymentItem additional_display_item;
additional_display_item.label = "Amex discount";
additional_display_item.amount->value = "-0.01";
additional_display_item.amount->currency = "USD";
modifier.additional_display_items.push_back(additional_display_item);
web_payment_request.details.modifiers.push_back(modifier);
TestPaymentRequest payment_request(web_payment_request,
chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
AutofillPaymentInstrument* selected_payment_method =
static_cast<AutofillPaymentInstrument*>(
payment_request.selected_payment_method());
EXPECT_EQ("Total", payment_request.GetTotal(selected_payment_method).label);
EXPECT_EQ("1.00",
payment_request.GetTotal(selected_payment_method).amount->value);
ASSERT_EQ(1U,
payment_request.GetDisplayItems(selected_payment_method).size());
}
// Tests that the modifier should get applied when the card network is a match.
TEST_F(PaymentRequestTest, PaymentDetailsModifier_BasicCard_NetworkMatch) {
autofill::AutofillProfile address = autofill::test::GetFullProfile();
test_personal_data_manager_.AddProfile(address);
autofill::CreditCard credit_card = autofill::test::GetCreditCard2(); // Amex.
credit_card.set_billing_address_id(address.guid());
test_personal_data_manager_.AddCreditCard(credit_card);
WebPaymentRequest web_payment_request =
payment_request_test_util::CreateTestWebPaymentRequest();
PaymentDetailsModifier modifier;
modifier.method_data.supported_method = "basic-card";
modifier.method_data.supported_networks.push_back("amex");
modifier.total = std::make_unique<payments::PaymentItem>();
modifier.total->label = "Discounted Total";
modifier.total->amount->value = "0.99";
modifier.total->amount->currency = "USD";
payments::PaymentItem additional_display_item;
additional_display_item.label = "Amex discount";
additional_display_item.amount->value = "-0.01";
additional_display_item.amount->currency = "USD";
modifier.additional_display_items.push_back(additional_display_item);
web_payment_request.details.modifiers.push_back(modifier);
TestPaymentRequest payment_request(web_payment_request,
chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
AutofillPaymentInstrument* selected_payment_method =
static_cast<AutofillPaymentInstrument*>(
payment_request.selected_payment_method());
EXPECT_EQ("Discounted Total",
payment_request.GetTotal(selected_payment_method).label);
EXPECT_EQ("0.99",
payment_request.GetTotal(selected_payment_method).amount->value);
ASSERT_EQ(2U,
payment_request.GetDisplayItems(selected_payment_method).size());
EXPECT_EQ("Subtotal",
payment_request.GetDisplayItems(selected_payment_method)[0].label);
EXPECT_EQ("1.00", payment_request.GetDisplayItems(selected_payment_method)[0]
.amount->value);
EXPECT_EQ("Amex discount",
payment_request.GetDisplayItems(selected_payment_method)[1].label);
EXPECT_EQ("-0.01", payment_request.GetDisplayItems(selected_payment_method)[1]
.amount->value);
}
// Tests that the modifier should not get applied when the card type is not
// supported.
TEST_F(PaymentRequestTest, PaymentDetailsModifier_BasicCard_TypeMismatch) {
autofill::AutofillProfile address = autofill::test::GetFullProfile();
test_personal_data_manager_.AddProfile(address);
autofill::CreditCard credit_card = autofill::test::GetCreditCard2(); // Amex.
test_personal_data_manager_.AddCreditCard(credit_card);
credit_card.set_billing_address_id(address.guid());
WebPaymentRequest web_payment_request =
payment_request_test_util::CreateTestWebPaymentRequest();
PaymentDetailsModifier modifier;
modifier.method_data.supported_method = "basic-card";
modifier.method_data.supported_networks.push_back("amex");
modifier.method_data.supported_types.insert(
autofill::CreditCard::CARD_TYPE_CREDIT);
modifier.total = std::make_unique<payments::PaymentItem>();
modifier.total->label = "Discounted Total";
modifier.total->amount->value = "0.99";
modifier.total->amount->currency = "USD";
payments::PaymentItem additional_display_item;
additional_display_item.label = "Amex discount";
additional_display_item.amount->value = "-0.01";
additional_display_item.amount->currency = "USD";
modifier.additional_display_items.push_back(additional_display_item);
web_payment_request.details.modifiers.push_back(modifier);
TestPaymentRequest payment_request(web_payment_request,
chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
AutofillPaymentInstrument* selected_payment_method =
static_cast<AutofillPaymentInstrument*>(
payment_request.selected_payment_method());
EXPECT_EQ("Total", payment_request.GetTotal(selected_payment_method).label);
EXPECT_EQ("1.00",
payment_request.GetTotal(selected_payment_method).amount->value);
ASSERT_EQ(1U,
payment_request.GetDisplayItems(selected_payment_method).size());
}
// Tests that the modifier should get applied when the card network and the type
// are both a match.
TEST_F(PaymentRequestTest,
PaymentDetailsModifier_BasicCard_NetworkAndTypeMatch) {
autofill::AutofillProfile address = autofill::test::GetFullProfile();
test_personal_data_manager_.AddProfile(address);
autofill::CreditCard credit_card = autofill::test::GetMaskedServerCardAmex();
credit_card.set_card_type(autofill::CreditCard::CardType::CARD_TYPE_CREDIT);
credit_card.set_billing_address_id(address.guid());
test_personal_data_manager_.AddServerCreditCard(credit_card);
WebPaymentRequest web_payment_request =
payment_request_test_util::CreateTestWebPaymentRequest();
PaymentDetailsModifier modifier;
modifier.method_data.supported_method = "basic-card";
modifier.method_data.supported_networks.push_back("amex");
modifier.method_data.supported_types.insert(
autofill::CreditCard::CARD_TYPE_CREDIT);
modifier.total = std::make_unique<payments::PaymentItem>();
modifier.total->label = "Discounted Total";
modifier.total->amount->value = "0.99";
modifier.total->amount->currency = "USD";
payments::PaymentItem additional_display_item;
additional_display_item.label = "Amex discount";
additional_display_item.amount->value = "-0.01";
additional_display_item.amount->currency = "USD";
modifier.additional_display_items.push_back(additional_display_item);
web_payment_request.details.modifiers.push_back(modifier);
TestPaymentRequest payment_request(web_payment_request,
chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
AutofillPaymentInstrument* selected_payment_method =
static_cast<AutofillPaymentInstrument*>(
payment_request.selected_payment_method());
EXPECT_EQ("Discounted Total",
payment_request.GetTotal(selected_payment_method).label);
EXPECT_EQ("0.99",
payment_request.GetTotal(selected_payment_method).amount->value);
ASSERT_EQ(2U,
payment_request.GetDisplayItems(selected_payment_method).size());
EXPECT_EQ("Subtotal",
payment_request.GetDisplayItems(selected_payment_method)[0].label);
EXPECT_EQ("1.00", payment_request.GetDisplayItems(selected_payment_method)[0]
.amount->value);
EXPECT_EQ("Amex discount",
payment_request.GetDisplayItems(selected_payment_method)[1].label);
EXPECT_EQ("-0.01", payment_request.GetDisplayItems(selected_payment_method)[1]
.amount->value);
}
// Tests that payment_request_util::RequestContactInfo returns true if payer's
// name, phone number, or email address are requested and false otherwise.
TEST_F(PaymentRequestTest, RequestContactInfo) {
payments::WebPaymentRequest web_payment_request;
web_payment_request.options.request_payer_name = true;
web_payment_request.options.request_payer_phone = true;
web_payment_request.options.request_payer_email = true;
payments::TestPaymentRequest payment_request1(
web_payment_request, chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
EXPECT_TRUE(payment_request1.RequestContactInfo());
web_payment_request.options.request_payer_name = false;
payments::TestPaymentRequest payment_request2(
web_payment_request, chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
EXPECT_TRUE(payment_request2.RequestContactInfo());
web_payment_request.options.request_payer_phone = false;
payments::TestPaymentRequest payment_request3(
web_payment_request, chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
EXPECT_TRUE(payment_request3.RequestContactInfo());
web_payment_request.options.request_payer_email = false;
payments::TestPaymentRequest payment_request4(
web_payment_request, chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
EXPECT_FALSE(payment_request4.RequestContactInfo());
}
// Tests the return value of payment_request_util::CanPay.
TEST_F(PaymentRequestTest, CanPay) {
payments::WebPaymentRequest web_payment_request;
payments::PaymentMethodData method_datum;
method_datum.supported_method = "basic-card";
method_datum.supported_networks.push_back("visa");
web_payment_request.method_data.push_back(method_datum);
// No selected payment method.
payments::TestPaymentRequest payment_request1(
web_payment_request, chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
EXPECT_FALSE(payment_request1.IsAbleToPay());
autofill::AutofillProfile profile = autofill::test::GetFullProfile();
// Make the profile incomplete by removing the name and the phone number so
// that it is not selected as the default shipping address or contact info.
profile.SetInfo(autofill::AutofillType(autofill::NAME_FULL), base::string16(),
"en-US");
profile.SetInfo(autofill::AutofillType(autofill::PHONE_HOME_WHOLE_NUMBER),
base::string16(), "en-US");
test_personal_data_manager_.AddProfile(profile);
autofill::CreditCard card = autofill::test::GetCreditCard(); // Visa.
card.set_billing_address_id(profile.guid());
test_personal_data_manager_.AddCreditCard(card);
// Has a selected payment method.
payments::TestPaymentRequest payment_request2(
web_payment_request, chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
EXPECT_TRUE(payment_request2.IsAbleToPay());
// No selected contact info.
web_payment_request.options.request_payer_phone = true;
payments::TestPaymentRequest payment_request3(
web_payment_request, chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
EXPECT_FALSE(payment_request3.IsAbleToPay());
test_personal_data_manager_.GetProfiles()[0]->SetInfo(
autofill::AutofillType(autofill::PHONE_HOME_WHOLE_NUMBER),
base::ASCIIToUTF16("16502111111"), "en-US");
// Has a selected contact info.
payments::TestPaymentRequest payment_request4(
web_payment_request, chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
EXPECT_TRUE(payment_request4.IsAbleToPay());
// No selected shipping address.
web_payment_request.options.request_shipping = true;
payments::TestPaymentRequest payment_request5(
web_payment_request, chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
EXPECT_FALSE(payment_request5.IsAbleToPay());
profile.SetInfo(autofill::AutofillType(autofill::NAME_FULL),
base::ASCIIToUTF16("John Doe"), "en-US");
// Has a selected shipping address, but no selected shipping option.
payments::TestPaymentRequest payment_request6(
web_payment_request, chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
EXPECT_FALSE(payment_request6.IsAbleToPay());
std::vector<payments::PaymentShippingOption> shipping_options;
payments::PaymentShippingOption option;
option.id = "1";
option.selected = true;
shipping_options.push_back(std::move(option));
web_payment_request.details.shipping_options = std::move(shipping_options);
// Has a selected shipping address and a selected shipping option.
payments::TestPaymentRequest payment_request7(
web_payment_request, chrome_browser_state_.get(), &web_state_,
&test_personal_data_manager_);
EXPECT_TRUE(payment_request7.IsAbleToPay());
}
} // namespace payments