blob: 3bfa54680c50b33bbd9ab65d90d25d12fd2c711f [file] [log] [blame]
// Copyright 2019 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/payments/credit_card_cvc_authenticator.h"
#include <stddef.h>
#include <algorithm>
#include <memory>
#include <string>
#include <tuple>
#include <utility>
#include <vector>
#include "base/base64.h"
#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/memory/ref_counted.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/metrics_hashes.h"
#include "base/stl_util.h"
#include "base/strings/string16.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "components/autofill/core/browser/autocomplete_history_manager.h"
#include "components/autofill/core/browser/autofill_download_manager.h"
#include "components/autofill/core/browser/autofill_test_utils.h"
#include "components/autofill/core/browser/data_model/autofill_profile.h"
#include "components/autofill/core/browser/data_model/credit_card.h"
#include "components/autofill/core/browser/metrics/form_events.h"
#include "components/autofill/core/browser/payments/test_authentication_requester.h"
#include "components/autofill/core/browser/payments/test_payments_client.h"
#include "components/autofill/core/browser/personal_data_manager.h"
#include "components/autofill/core/browser/test_autofill_client.h"
#include "components/autofill/core/browser/test_autofill_clock.h"
#include "components/autofill/core/browser/test_autofill_driver.h"
#include "components/autofill/core/browser/test_personal_data_manager.h"
#include "components/autofill/core/browser/validation.h"
#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
#include "components/autofill/core/common/autofill_clock.h"
#include "components/autofill/core/common/autofill_features.h"
#include "components/autofill/core/common/autofill_payments_features.h"
#include "components/autofill/core/common/autofill_prefs.h"
#include "components/autofill/core/common/autofill_switches.h"
#include "components/autofill/core/common/autofill_util.h"
#include "components/prefs/pref_service.h"
#include "components/security_state/core/security_state.h"
#include "components/strings/grit/components_strings.h"
#include "components/sync/driver/test_sync_service.h"
#include "components/variations/variations_associated_data.h"
#include "components/variations/variations_params_manager.h"
#include "components/version_info/channel.h"
#include "net/base/url_util.h"
#include "net/url_request/url_request_context_getter.h"
#include "net/url_request/url_request_test_util.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/geometry/rect.h"
#include "url/gurl.h"
using base::ASCIIToUTF16;
namespace autofill {
namespace {
const char kTestGUID[] = "00000000-0000-0000-0000-000000000001";
const char kTestNumber[] = "4234567890123456"; // Visa
std::string NextYear() {
base::Time::Exploded now;
base::Time::Now().LocalExplode(&now);
return base::NumberToString(now.year + 1);
}
std::string NextMonth() {
base::Time::Exploded now;
base::Time::Now().LocalExplode(&now);
return base::NumberToString(now.month % 12 + 1);
}
} // namespace
class CreditCardCVCAuthenticatorTest : public testing::Test {
public:
CreditCardCVCAuthenticatorTest() {}
void SetUp() override {
autofill_client_.SetPrefs(test::PrefServiceForTesting());
personal_data_manager_.Init(/*profile_database=*/database_,
/*account_database=*/nullptr,
/*pref_service=*/autofill_client_.GetPrefs(),
/*identity_manager=*/nullptr,
/*client_profile_validator=*/nullptr,
/*history_service=*/nullptr,
/*is_off_the_record=*/false);
personal_data_manager_.SetPrefService(autofill_client_.GetPrefs());
requester_.reset(new TestAuthenticationRequester());
autofill_driver_ =
std::make_unique<testing::NiceMock<TestAutofillDriver>>();
request_context_ = new net::TestURLRequestContextGetter(
base::ThreadTaskRunnerHandle::Get());
autofill_driver_->SetURLRequestContext(request_context_.get());
payments::TestPaymentsClient* payments_client =
new payments::TestPaymentsClient(
autofill_driver_->GetURLLoaderFactory(),
autofill_client_.GetIdentityManager(), &personal_data_manager_);
autofill_client_.set_test_payments_client(
std::unique_ptr<payments::TestPaymentsClient>(payments_client));
cvc_authenticator_ =
std::make_unique<CreditCardCVCAuthenticator>(&autofill_client_);
}
void TearDown() override {
// Order of destruction is important as AutofillDriver relies on
// PersonalDataManager to be around when it gets destroyed.
autofill_driver_.reset();
personal_data_manager_.SetPrefService(nullptr);
personal_data_manager_.ClearCreditCards();
request_context_ = nullptr;
}
CreditCard CreateServerCard(std::string guid, std::string number) {
CreditCard masked_server_card = CreditCard();
test::SetCreditCardInfo(&masked_server_card, "Elvis Presley",
number.c_str(), NextMonth().c_str(),
NextYear().c_str(), "1");
masked_server_card.set_guid(guid);
masked_server_card.set_record_type(CreditCard::MASKED_SERVER_CARD);
personal_data_manager_.ClearCreditCards();
personal_data_manager_.AddServerCreditCard(masked_server_card);
return masked_server_card;
}
void OnDidGetRealPan(AutofillClient::PaymentsRpcResult result,
const std::string& real_pan) {
payments::FullCardRequest* full_card_request =
cvc_authenticator_->full_card_request_.get();
DCHECK(full_card_request);
full_card_request->OnDidGetRealPan(result, real_pan);
}
protected:
std::unique_ptr<TestAuthenticationRequester> requester_;
base::test::ScopedTaskEnvironment scoped_task_environment_;
TestAutofillClient autofill_client_;
std::unique_ptr<TestAutofillDriver> autofill_driver_;
scoped_refptr<net::TestURLRequestContextGetter> request_context_;
scoped_refptr<AutofillWebDataService> database_;
TestPersonalDataManager personal_data_manager_;
base::test::ScopedFeatureList scoped_feature_list_;
std::unique_ptr<CreditCardCVCAuthenticator> cvc_authenticator_;
};
TEST_F(CreditCardCVCAuthenticatorTest, AuthenticateServerCardSuccess) {
CreditCard card = CreateServerCard(kTestGUID, kTestNumber);
cvc_authenticator_->Authenticate(&card, requester_->GetWeakPtr(),
&personal_data_manager_,
base::TimeTicks::Now());
OnDidGetRealPan(AutofillClient::SUCCESS, kTestNumber);
EXPECT_TRUE(requester_->did_succeed());
EXPECT_EQ(ASCIIToUTF16(kTestNumber), requester_->number());
}
TEST_F(CreditCardCVCAuthenticatorTest, AuthenticateServerCardNetworkError) {
CreditCard card = CreateServerCard(kTestGUID, kTestNumber);
cvc_authenticator_->Authenticate(&card, requester_->GetWeakPtr(),
&personal_data_manager_,
base::TimeTicks::Now());
OnDidGetRealPan(AutofillClient::NETWORK_ERROR, std::string());
EXPECT_FALSE(requester_->did_succeed());
}
TEST_F(CreditCardCVCAuthenticatorTest, AuthenticateServerCardPermanentFailure) {
CreditCard card = CreateServerCard(kTestGUID, kTestNumber);
cvc_authenticator_->Authenticate(&card, requester_->GetWeakPtr(),
&personal_data_manager_,
base::TimeTicks::Now());
OnDidGetRealPan(AutofillClient::PERMANENT_FAILURE, std::string());
EXPECT_FALSE(requester_->did_succeed());
}
TEST_F(CreditCardCVCAuthenticatorTest, AuthenticateServerCardTryAgainFailure) {
CreditCard card = CreateServerCard(kTestGUID, kTestNumber);
cvc_authenticator_->Authenticate(&card, requester_->GetWeakPtr(),
&personal_data_manager_,
base::TimeTicks::Now());
OnDidGetRealPan(AutofillClient::TRY_AGAIN_FAILURE, std::string());
EXPECT_FALSE(requester_->did_succeed());
OnDidGetRealPan(AutofillClient::SUCCESS, kTestNumber);
EXPECT_TRUE(requester_->did_succeed());
EXPECT_EQ(ASCIIToUTF16(kTestNumber), requester_->number());
}
} // namespace autofill