diff options
author | ahutter@chromium.org <ahutter@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-20 05:56:25 +0000 |
---|---|---|
committer | ahutter@chromium.org <ahutter@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-20 05:56:25 +0000 |
commit | 2ed98218eff6b91754593cd75c9846472757d1ac (patch) | |
tree | aae737b227d1500fbd7197e4f78327f52934f1e1 /components/autofill/content/browser/wallet | |
parent | 47021af6a5368ced2a2fb7b47f151f8c0a068de5 (diff) | |
download | chromium_src-2ed98218eff6b91754593cd75c9846472757d1ac.zip chromium_src-2ed98218eff6b91754593cd75c9846472757d1ac.tar.gz chromium_src-2ed98218eff6b91754593cd75c9846472757d1ac.tar.bz2 |
New encryption/escrow endpoints for Wallet
No more EncryptionEscrowClient!
Updates Wallet client to use new endpoints for AuthenticateInstrument, GetFullWallet, and SaveToWallet and reduces all those calls to just one roundtrip.
No more confusing Save/Update... calls, just one SaveToWallet call.
Still need to manually test SaveToWallet and AuthenticateInstrument.
TEST=unit tests all still pass with minimal changes, manual testing of GetFullWallet
BUG=249958,245341,238807
Review URL: https://chromiumcodereview.appspot.com/17970003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@212754 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'components/autofill/content/browser/wallet')
16 files changed, 591 insertions, 1669 deletions
diff --git a/components/autofill/content/browser/wallet/encryption_escrow_client.h b/components/autofill/content/browser/wallet/encryption_escrow_client.h deleted file mode 100644 index 456c972..0000000 --- a/components/autofill/content/browser/wallet/encryption_escrow_client.h +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright 2013 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_CONTENT_BROWSER_WALLET_ENCRYPTION_ESCROW_CLIENT_H_ -#define COMPONENTS_AUTOFILL_CONTENT_BROWSER_WALLET_ENCRYPTION_ESCROW_CLIENT_H_ - -#include <string> -#include <vector> - -#include "base/memory/ref_counted.h" -#include "net/url_request/url_fetcher_delegate.h" - -class GURL; - -namespace net { -class URLFetcher; -class URLRequestContextGetter; -} - -namespace autofill { -namespace wallet { - -class EncryptionEscrowClientObserver; -class Instrument; - -// EncrytionEscrowClient is responsible for making calls to the Online Wallet -// encryption and escrow backend. -class EncryptionEscrowClient : public net::URLFetcherDelegate { - public: - // |observer| must outlive |this|. - EncryptionEscrowClient(net::URLRequestContextGetter* context_getter, - EncryptionEscrowClientObserver* observer); - virtual ~EncryptionEscrowClient(); - - // Sends |one_time_pad|, a vector of cryptographically secure random bytes, to - // Online Wallet to be encrypted. These bytes must be generated using - // crypto/random.h. - void EncryptOneTimePad(const std::vector<uint8>& one_time_pad); - - // Escrows the primary account number and card verfication number of - // |new_instrument| with Online Wallet. The escrow is keyed off of - // |obfuscated_gaia_id|. - void EscrowInstrumentInformation(const Instrument& new_instrument, - const std::string& obfuscated_gaia_id); - - // Escrows the card verfication number of an existing instrument with Online - // Wallet. The escrow is keyed off of |obfuscated_gaia_id|. - void EscrowCardVerificationNumber(const std::string& card_verification_number, - const std::string& obfuscated_gaia_id); - - // Cancels |request_| (if it exists). - void CancelRequest(); - - bool HasRequestInProgress() const; - - protected: - // Exposed for testing. - const net::URLFetcher* request() const { return request_.get(); } - - private: - enum RequestType { - NO_PENDING_REQUEST, - ENCRYPT_ONE_TIME_PAD, - ESCROW_INSTRUMENT_INFORMATION, - ESCROW_CARD_VERIFICATION_NUMBER, - }; - - // Posts |post_body| to |url|. When the request is complete, |observer_| is - // notified of the result. - void MakeRequest(const GURL& url, const std::string& post_body); - - // Performs bookkeeping tasks for any invalid requests. - void HandleMalformedResponse(net::URLFetcher* request); - - // net::URLFetcherDelegate: - virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE; - - // The context for the request. Ensures the gdToken cookie is set as a header - // in the requests to Online Wallet if it is present. - scoped_refptr<net::URLRequestContextGetter> context_getter_; - - // Observer class that has its various On* methods called based on the results - // of a request to Online Wallet. - EncryptionEscrowClientObserver* const observer_; - - // The current request object. - scoped_ptr<net::URLFetcher> request_; - - // The type of the current request. Must be NO_PENDING_REQUEST for a request - // to be initiated as only one request may be running at a given time. - RequestType request_type_; - - DISALLOW_COPY_AND_ASSIGN(EncryptionEscrowClient); -}; - -} // namespace wallet -} // namespace autofill - -#endif // COMPONENTS_AUTOFILL_CONTENT_BROWSER_WALLET_ENCRYPTION_ESCROW_CLIENT_H_ diff --git a/components/autofill/content/browser/wallet/encryption_escrow_client_observer.h b/components/autofill/content/browser/wallet/encryption_escrow_client_observer.h deleted file mode 100644 index 964113c..0000000 --- a/components/autofill/content/browser/wallet/encryption_escrow_client_observer.h +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2013 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_CONTENT_BROWSER_WALLET_ENCRYPTION_ESCROW_CLIENT_OBSERVER_H_ -#define COMPONENTS_AUTOFILL_CONTENT_BROWSER_WALLET_ENCRYPTION_ESCROW_CLIENT_OBSERVER_H_ - -#include <string> - -namespace autofill { -namespace wallet { - -// EncryptionEscrowClientObserver is to be implemented by any classes making -// calls with EncryptionEscrowClient. The appropriate callback method will be -// called on EncryptionEscrowClientObserver with the response from the Online -// Wallet encryption and escrow backend. -class EncryptionEscrowClientObserver { - public: - // Called when an EncryptOneTimePad request finishes successfully. - // |encrypted_one_time_pad| and |session_material| must be used when getting a - // FullWallet. - virtual void OnDidEncryptOneTimePad(const std::string& encrypted_one_time_pad, - const std::string& session_material) = 0; - - // Called when an EscrowCardVerificationNumber request finishes - // successfully. |escrow_handle| must be used when authenticating an - // instrument. - virtual void OnDidEscrowCardVerificationNumber( - const std::string& escrow_handle) = 0; - - // Called when an EscrowInstrumentInformation request finishes successfully. - // |escrow_handle| must be used when saving a new instrument. - virtual void OnDidEscrowInstrumentInformation( - const std::string& escrow_handle) = 0; - - // Called when a request is made to the encryption escrow server. - virtual void OnDidMakeRequest() = 0; - - // Called when a request fails due to a network error or if the response was - // invalid. - virtual void OnNetworkError() = 0; - - // Called when a request fails due to a malformed response. - virtual void OnMalformedResponse() = 0; - - protected: - virtual ~EncryptionEscrowClientObserver() {} -}; - -} // namespace wallet -} // namespace autofill - -#endif // COMPONENTS_AUTOFILL_CONTENT_BROWSER_WALLET_ENCRYPTION_ESCROW_CLIENT_OBSERVER_H_ diff --git a/components/autofill/content/browser/wallet/encryption_escrow_client_unittest.cc b/components/autofill/content/browser/wallet/encryption_escrow_client_unittest.cc deleted file mode 100644 index 82903c5b..0000000 --- a/components/autofill/content/browser/wallet/encryption_escrow_client_unittest.cc +++ /dev/null @@ -1,196 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/memory/scoped_ptr.h" -#include "components/autofill/content/browser/wallet/encryption_escrow_client.h" -#include "components/autofill/content/browser/wallet/encryption_escrow_client_observer.h" -#include "components/autofill/content/browser/wallet/instrument.h" -#include "components/autofill/content/browser/wallet/wallet_test_util.h" -#include "content/public/test/test_browser_context.h" -#include "content/public/test/test_browser_thread.h" -#include "net/base/net_errors.h" -#include "net/http/http_status_code.h" -#include "net/url_request/test_url_fetcher_factory.h" -#include "net/url_request/url_fetcher_delegate.h" -#include "net/url_request/url_request_status.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace autofill { -namespace wallet { - -namespace { - -const char kEncryptOtpRequest[] = "cvv=30:000102030405"; -const char kEncryptOtpResponse[] = "session_material|encrypted_one_time_pad"; -const char kEscrowInstrumentInformationRequest[] = - "gid=obfuscated_gaia_id&cardNumber=4444444444444448&cvv=123"; -const char kEscrowCardVerificationNumberRequest[] = - "gid=obfuscated_gaia_id&cvv=123"; - -class MockEncryptionEscrowClientObserver : - public EncryptionEscrowClientObserver, - public base::SupportsWeakPtr<MockEncryptionEscrowClientObserver> { - public: - MockEncryptionEscrowClientObserver() {} - ~MockEncryptionEscrowClientObserver() {} - - MOCK_METHOD2(OnDidEncryptOneTimePad, - void(const std::string& encrypted_one_time_pad, - const std::string& session_material)); - MOCK_METHOD1(OnDidEscrowCardVerificationNumber, - void(const std::string& escrow_handle)); - MOCK_METHOD1(OnDidEscrowInstrumentInformation, - void(const std::string& escrow_handle)); - MOCK_METHOD0(OnDidMakeRequest, void()); - MOCK_METHOD0(OnMalformedResponse, void()); - MOCK_METHOD0(OnNetworkError, void()); -}; - -} // namespace - -class TestEncryptionEscrowClient : public EncryptionEscrowClient { - public: - TestEncryptionEscrowClient( - net::URLRequestContextGetter* context_getter, - EncryptionEscrowClientObserver* observer) - : EncryptionEscrowClient(context_getter, observer) {} - - bool HasRequestInProgress() const { - return request() != NULL; - } -}; - -class EncryptionEscrowClientTest : public testing::Test { - public: - EncryptionEscrowClientTest() - : instrument_(GetTestInstrument()) {} - - virtual void SetUp() OVERRIDE { - encryption_escrow_client_.reset(new TestEncryptionEscrowClient( - browser_context_.GetRequestContext(), &observer_)); - } - - virtual void TearDown() OVERRIDE { - encryption_escrow_client_.reset(); - } - - std::vector<uint8> MakeOneTimePad() { - std::vector<uint8> one_time_pad; - one_time_pad.push_back(0); - one_time_pad.push_back(1); - one_time_pad.push_back(2); - one_time_pad.push_back(3); - one_time_pad.push_back(4); - one_time_pad.push_back(5); - return one_time_pad; - } - - void VerifyAndFinishRequest(net::HttpStatusCode response_code, - const std::string& request_body, - const std::string& response_body) { - net::TestURLFetcher* fetcher = factory_.GetFetcherByID(1); - ASSERT_TRUE(fetcher); - EXPECT_EQ(request_body, fetcher->upload_data()); - fetcher->set_response_code(response_code); - fetcher->SetResponseString(response_body); - fetcher->delegate()->OnURLFetchComplete(fetcher); - } - - protected: - scoped_ptr<TestEncryptionEscrowClient> encryption_escrow_client_; - testing::StrictMock<MockEncryptionEscrowClientObserver> observer_; - scoped_ptr<Instrument> instrument_; - - - private: - content::TestBrowserContext browser_context_; - net::TestURLFetcherFactory factory_; -}; - -TEST_F(EncryptionEscrowClientTest, NetworkError) { - EXPECT_CALL(observer_, OnDidMakeRequest()).Times(1); - EXPECT_CALL(observer_, OnNetworkError()).Times(1); - - encryption_escrow_client_->EscrowInstrumentInformation(*instrument_, - "obfuscated_gaia_id"); - VerifyAndFinishRequest(net::HTTP_UNAUTHORIZED, - kEscrowInstrumentInformationRequest, - std::string()); -} - -TEST_F(EncryptionEscrowClientTest, EscrowInstrumentInformationSuccess) { - EXPECT_CALL(observer_, OnDidMakeRequest()).Times(1); - EXPECT_CALL(observer_, OnDidEscrowInstrumentInformation("abc")).Times(1); - - encryption_escrow_client_->EscrowInstrumentInformation(*instrument_, - "obfuscated_gaia_id"); - VerifyAndFinishRequest(net::HTTP_OK, - kEscrowInstrumentInformationRequest, - "abc"); -} - -TEST_F(EncryptionEscrowClientTest, EscrowInstrumentInformationFailure) { - EXPECT_CALL(observer_, OnDidMakeRequest()).Times(1); - EXPECT_CALL(observer_, OnMalformedResponse()).Times(1); - - encryption_escrow_client_->EscrowInstrumentInformation(*instrument_, - "obfuscated_gaia_id"); - VerifyAndFinishRequest(net::HTTP_OK, - kEscrowInstrumentInformationRequest, - std::string()); -} - -TEST_F(EncryptionEscrowClientTest, EscrowCardVerificationNumberSuccess) { - EXPECT_CALL(observer_, OnDidMakeRequest()).Times(1); - EXPECT_CALL(observer_, OnDidEscrowCardVerificationNumber("abc")).Times(1); - - encryption_escrow_client_->EscrowCardVerificationNumber("123", - "obfuscated_gaia_id"); - VerifyAndFinishRequest(net::HTTP_OK, - kEscrowCardVerificationNumberRequest, - "abc"); -} - -TEST_F(EncryptionEscrowClientTest, EscrowCardVerificationNumberFailure) { - EXPECT_CALL(observer_, OnDidMakeRequest()).Times(1); - EXPECT_CALL(observer_, OnMalformedResponse()).Times(1); - - encryption_escrow_client_->EscrowCardVerificationNumber("123", - "obfuscated_gaia_id"); - VerifyAndFinishRequest(net::HTTP_OK, - kEscrowCardVerificationNumberRequest, - std::string()); -} - -TEST_F(EncryptionEscrowClientTest, EncryptOneTimePadSuccess) { - EXPECT_CALL(observer_, OnDidMakeRequest()).Times(1); - EXPECT_CALL(observer_, - OnDidEncryptOneTimePad("encrypted_one_time_pad", - "session_material")).Times(1); - - encryption_escrow_client_->EncryptOneTimePad(MakeOneTimePad()); - VerifyAndFinishRequest(net::HTTP_OK, kEncryptOtpRequest, kEncryptOtpResponse); -} - -TEST_F(EncryptionEscrowClientTest, EncryptOneTimePadFailure) { - EXPECT_CALL(observer_, OnDidMakeRequest()).Times(1); - EXPECT_CALL(observer_, OnMalformedResponse()).Times(1); - - encryption_escrow_client_->EncryptOneTimePad(MakeOneTimePad()); - VerifyAndFinishRequest(net::HTTP_OK, kEncryptOtpRequest, std::string()); -} - -TEST_F(EncryptionEscrowClientTest, CancelRequest) { - EXPECT_CALL(observer_, OnDidMakeRequest()).Times(1); - - encryption_escrow_client_->EncryptOneTimePad(MakeOneTimePad()); - EXPECT_TRUE(encryption_escrow_client_->HasRequestInProgress()); - - encryption_escrow_client_->CancelRequest(); - EXPECT_FALSE(encryption_escrow_client_->HasRequestInProgress()); -} - -} // namespace wallet -} // namespace autofill diff --git a/components/autofill/content/browser/wallet/instrument.cc b/components/autofill/content/browser/wallet/instrument.cc index 5e1c8c7..d50bc45 100644 --- a/components/autofill/content/browser/wallet/instrument.cc +++ b/components/autofill/content/browser/wallet/instrument.cc @@ -80,7 +80,6 @@ Instrument::Instrument(const base::string16& primary_account_number, expiration_year_(expiration_year), form_of_payment_(form_of_payment), address_(address.Pass()) { - DCHECK(address_); Init(); } @@ -90,7 +89,8 @@ Instrument::Instrument(const Instrument& instrument) expiration_month_(instrument.expiration_month()), expiration_year_(instrument.expiration_year()), form_of_payment_(instrument.form_of_payment()), - address_(new Address(instrument.address())) { + address_(instrument.address() ? + new Address(*instrument.address()) : NULL) { Init(); } @@ -114,22 +114,6 @@ scoped_ptr<base::DictionaryValue> Instrument::ToDictionary() const { return dict.Pass(); } -bool Instrument::IsValid() const { - if (!IsStringASCII(primary_account_number_)) - return false; - bool primary_account_number_valid = - autofill::IsValidCreditCardNumber(primary_account_number_); - bool card_verification_number_valid = card_verification_number_.size() == 3 || - card_verification_number_.size() == 4; - bool exp_month_valid = expiration_month_ >= 1 && expiration_month_ <= 12; - bool exp_year_valid = expiration_year_ >= 2013 && expiration_year_ <= 2100; - - return primary_account_number_valid && - card_verification_number_valid && - exp_month_valid && - exp_year_valid; -} - void Instrument::Init() { if (primary_account_number_.size() >= 4) { last_four_digits_ = diff --git a/components/autofill/content/browser/wallet/instrument.h b/components/autofill/content/browser/wallet/instrument.h index 6c91ea1..b706a7e 100644 --- a/components/autofill/content/browser/wallet/instrument.h +++ b/components/autofill/content/browser/wallet/instrument.h @@ -55,10 +55,6 @@ class Instrument { scoped_ptr<base::DictionaryValue> ToDictionary() const; - // Users of this class should call IsValid to check that the inputs provided - // in the constructor were valid for use with Google Wallet. - bool IsValid() const; - const base::string16& primary_account_number() const { return primary_account_number_; } @@ -67,9 +63,11 @@ class Instrument { } int expiration_month() const { return expiration_month_; } int expiration_year() const { return expiration_year_; } - const Address& address() const { return *address_; } + const Address* address() const { return address_.get(); } FormOfPayment form_of_payment() const { return form_of_payment_; } const base::string16& last_four_digits() const { return last_four_digits_; } + const std::string& object_id() const { return object_id_; } + void set_object_id(const std::string& object_id) { object_id_ = object_id; } private: void Init(); @@ -95,6 +93,9 @@ class Instrument { // The last four digits of |primary_account_number_|. base::string16 last_four_digits_; + // Externalized Online Wallet id for this instrument. + std::string object_id_; + DISALLOW_ASSIGN(Instrument); }; diff --git a/components/autofill/content/browser/wallet/instrument_unittest.cc b/components/autofill/content/browser/wallet/instrument_unittest.cc index f4b9ee8..b5f273f 100644 --- a/components/autofill/content/browser/wallet/instrument_unittest.cc +++ b/components/autofill/content/browser/wallet/instrument_unittest.cc @@ -29,128 +29,6 @@ TEST(Instrument, LastFourDigits) { GetTestShippingAddress().Pass()); EXPECT_EQ(ASCIIToUTF16(kLastFourDigits), instrument.last_four_digits()); - EXPECT_TRUE(instrument.IsValid()); -} - -TEST(Instrument, NoPrimaryAccountNumberIsInvalid) { - Instrument instrument(base::string16(), - ASCIIToUTF16(kCardVerificationNumber), - 12, - 2015, - Instrument::VISA, - GetTestShippingAddress().Pass()); - - EXPECT_FALSE(instrument.IsValid()); -} - -TEST(Instrument, TooShortPrimaryAccountNumberIsInvalid) { - Instrument instrument(ASCIIToUTF16("44447"), - ASCIIToUTF16(kCardVerificationNumber), - 12, - 2015, - Instrument::VISA, - GetTestShippingAddress().Pass()); - - EXPECT_FALSE(instrument.IsValid()); -} - -TEST(Instrument, TooLongPrimaryAccountNumberIsInvalid) { - Instrument instrument(ASCIIToUTF16("44444444444444444448"), - ASCIIToUTF16(kCardVerificationNumber), - 12, - 2015, - Instrument::VISA, - GetTestShippingAddress().Pass()); - - EXPECT_FALSE(instrument.IsValid()); -} - -TEST(Instrument, PrimaryAccountNumberNotPassingLuhnIsInvalid) { - Instrument instrument(ASCIIToUTF16("4444444444444444"), - ASCIIToUTF16(kCardVerificationNumber), - 12, - 2015, - Instrument::VISA, - GetTestShippingAddress().Pass()); - - EXPECT_FALSE(instrument.IsValid()); -} - -TEST(Instrument, NoCardVerificationNumberIsInvalid) { - Instrument instrument(ASCIIToUTF16(kPrimaryAccountNumber), - base::string16(), - 12, - 2015, - Instrument::VISA, - GetTestShippingAddress().Pass()); - - EXPECT_FALSE(instrument.IsValid()); -} - -TEST(Instrument, TooShortCardVerificationNumberIsInvalid) { - Instrument instrument(ASCIIToUTF16(kPrimaryAccountNumber), - ASCIIToUTF16("12"), - 12, - 2015, - Instrument::VISA, - GetTestShippingAddress().Pass()); - - EXPECT_FALSE(instrument.IsValid()); -} - -TEST(Instrument, TooLongCardVerificationNumberIsInvalid) { - Instrument instrument(ASCIIToUTF16(kPrimaryAccountNumber), - ASCIIToUTF16("12345"), - 12, - 2015, - Instrument::VISA, - GetTestShippingAddress().Pass()); - - EXPECT_FALSE(instrument.IsValid()); -} - -TEST(Instrument, ZeroAsExpirationMonthIsInvalid) { - Instrument instrument(ASCIIToUTF16(kPrimaryAccountNumber), - ASCIIToUTF16(kCardVerificationNumber), - 0, - 2015, - Instrument::VISA, - GetTestShippingAddress().Pass()); - - EXPECT_FALSE(instrument.IsValid()); -} - -TEST(Instrument, TooLargeExpirationMonthIsInvalid) { - Instrument instrument(ASCIIToUTF16(kPrimaryAccountNumber), - ASCIIToUTF16(kCardVerificationNumber), - 13, - 2015, - Instrument::VISA, - GetTestShippingAddress().Pass()); - - EXPECT_FALSE(instrument.IsValid()); -} - -TEST(Instrument, TooSmallExpirationYearIsInvalid) { - Instrument instrument(ASCIIToUTF16(kPrimaryAccountNumber), - ASCIIToUTF16(kCardVerificationNumber), - 12, - 999, - Instrument::VISA, - GetTestShippingAddress().Pass()); - - EXPECT_FALSE(instrument.IsValid()); -} - -TEST(Instrument, TooLargeExpirationYearIsInvalid) { - Instrument instrument(ASCIIToUTF16(kPrimaryAccountNumber), - ASCIIToUTF16(kCardVerificationNumber), - 12, - 10000, - Instrument::VISA, - GetTestShippingAddress().Pass()); - - EXPECT_FALSE(instrument.IsValid()); } TEST(Instrument, ToDictionary) { diff --git a/components/autofill/content/browser/wallet/mock_wallet_client.h b/components/autofill/content/browser/wallet/mock_wallet_client.h index 477fbac..c8d03b3 100644 --- a/components/autofill/content/browser/wallet/mock_wallet_client.h +++ b/components/autofill/content/browser/wallet/mock_wallet_client.h @@ -31,26 +31,24 @@ class MockWalletClient : public WalletClient { const std::string& google_transaction_id, const GURL& source_url)); - MOCK_METHOD3(AuthenticateInstrument, + MOCK_METHOD2(AuthenticateInstrument, void(const std::string& instrument_id, - const std::string& card_verification_number, - const std::string& obfuscated_gaia_id)); + const std::string& card_verification_number)); MOCK_METHOD1(GetFullWallet, void(const WalletClient::FullWalletRequest& request)); - MOCK_METHOD2(SaveAddress, - void(const Address& address, const GURL& source_url)); - - MOCK_METHOD3(SaveInstrument, - void(const Instrument& instrument, - const std::string& obfuscated_gaia_id, - const GURL& source_url)); + // Methods with scoped_ptrs can't be mocked but by using the implementation + // below the same effect can be achieved. + virtual void SaveToWallet(scoped_ptr<wallet::Instrument> instrument, + scoped_ptr<wallet::Address> address, + const GURL& source_url) OVERRIDE { + SaveToWalletMock(instrument.get(), address.get(), source_url); + } - MOCK_METHOD4(SaveInstrumentAndAddress, - void(const Instrument& instrument, - const Address& address, - const std::string& obfuscated_gaia_id, + MOCK_METHOD3(SaveToWalletMock, + void(Instrument* instrument, + Address* address, const GURL& source_url)); MOCK_METHOD4(SendAutocheckoutStatus, @@ -59,22 +57,7 @@ class MockWalletClient : public WalletClient { const std::vector<AutocheckoutStatistic>& latency_statistics, const std::string& google_transaction_id)); - MOCK_METHOD2(UpdateAddress, - void(const Address& address, const GURL& source_url)); - - virtual void UpdateInstrument( - const WalletClient::UpdateInstrumentRequest& update_request, - scoped_ptr<Address> billing_address) OVERRIDE { - updated_billing_address_ = billing_address.Pass(); - } - - const Address* updated_billing_address() { - return updated_billing_address_.get(); - } - private: - scoped_ptr<Address> updated_billing_address_; - DISALLOW_COPY_AND_ASSIGN(MockWalletClient); }; diff --git a/components/autofill/content/browser/wallet/wallet_client.cc b/components/autofill/content/browser/wallet/wallet_client.cc index 9e18185..aa82172 100644 --- a/components/autofill/content/browser/wallet/wallet_client.cc +++ b/components/autofill/content/browser/wallet/wallet_client.cc @@ -9,7 +9,10 @@ #include "base/json/json_writer.h" #include "base/logging.h" #include "base/memory/scoped_ptr.h" +#include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" +#include "base/strings/utf_string_conversions.h" #include "components/autofill/content/browser/wallet/form_field_error.h" #include "components/autofill/content/browser/wallet/instrument.h" #include "components/autofill/content/browser/wallet/wallet_address.h" @@ -19,6 +22,7 @@ #include "components/autofill/core/browser/autofill_metrics.h" #include "crypto/random.h" #include "google_apis/google_api_keys.h" +#include "net/base/escape.h" #include "net/http/http_status_code.h" #include "net/url_request/url_fetcher.h" #include "net/url_request/url_request_context_getter.h" @@ -29,9 +33,24 @@ namespace wallet { namespace { +const char kFormEncodedMimeType[] = "application/x-www-form-urlencoded"; const char kJsonMimeType[] = "application/json"; +const char kEscrowNewInstrumentFormat[] = + "request_content_type=application/json&request=%s&cvn=%s&card_number=%s"; +const char kEscrowCardVerificationNumberFormat[] = + "request_content_type=application/json&request=%s&cvn=%s"; +const char kGetFullWalletRequestFormat[] = + "request_content_type=application/json&request=%s&otp=%s:%s"; const size_t kOneTimePadLength = 6; +// The maximum number of bits in the one time pad that the server is willing to +// accept. +const size_t kMaxBits = 56; + +// The minimum number of bits in the one time pad that the server is willing to +// accept. +const size_t kMinBits = 40; + std::string AutocheckoutStatusToString(AutocheckoutStatus status) { switch (status) { case MISSING_FIELDMAPPING: @@ -241,23 +260,12 @@ WalletClient::FullWalletRequest::FullWalletRequest( WalletClient::FullWalletRequest::~FullWalletRequest() {} -WalletClient::UpdateInstrumentRequest::UpdateInstrumentRequest( - const std::string& instrument_id, - const GURL& source_url) - : instrument_id(instrument_id), - expiration_month(0), - expiration_year(0), - source_url(source_url) {} - -WalletClient::UpdateInstrumentRequest::~UpdateInstrumentRequest() {} - WalletClient::WalletClient(net::URLRequestContextGetter* context_getter, WalletClientDelegate* delegate) : context_getter_(context_getter), delegate_(delegate), request_type_(NO_PENDING_REQUEST), - one_time_pad_(kOneTimePadLength), - encryption_escrow_client_(context_getter, this) { + one_time_pad_(kOneTimePadLength) { DCHECK(context_getter_.get()); DCHECK(delegate_); } @@ -280,27 +288,37 @@ void WalletClient::AcceptLegalDocuments( void WalletClient::AuthenticateInstrument( const std::string& instrument_id, - const std::string& card_verification_number, - const std::string& obfuscated_gaia_id) { + const std::string& card_verification_number) { if (HasRequestInProgress()) { pending_requests_.push(base::Bind(&WalletClient::AuthenticateInstrument, base::Unretained(this), instrument_id, - card_verification_number, - obfuscated_gaia_id)); + card_verification_number)); return; } DCHECK_EQ(NO_PENDING_REQUEST, request_type_); - DCHECK(pending_request_body_.empty()); request_type_ = AUTHENTICATE_INSTRUMENT; - pending_request_body_.SetString(kApiKeyKey, google_apis::GetAPIKey()); - pending_request_body_.SetString(kRiskParamsKey, delegate_->GetRiskData()); - pending_request_body_.SetString(kInstrumentIdKey, instrument_id); + base::DictionaryValue request_dict; + request_dict.SetString(kApiKeyKey, google_apis::GetAPIKey()); + request_dict.SetString(kRiskParamsKey, delegate_->GetRiskData()); + request_dict.SetString(kInstrumentIdKey, instrument_id); + + std::string json_payload; + base::JSONWriter::Write(&request_dict, &json_payload); + + std::string escaped_card_verification_number = net::EscapeUrlEncodedData( + card_verification_number, true); + + std::string post_body = base::StringPrintf( + kEscrowCardVerificationNumberFormat, + net::EscapeUrlEncodedData(json_payload, true).c_str(), + escaped_card_verification_number.c_str()); - encryption_escrow_client_.EscrowCardVerificationNumber( - card_verification_number, obfuscated_gaia_id); + MakeWalletRequest(GetAuthenticateInstrumentUrl(), + post_body, + kFormEncodedMimeType); } void WalletClient::GetFullWallet(const FullWalletRequest& full_wallet_request) { @@ -312,23 +330,21 @@ void WalletClient::GetFullWallet(const FullWalletRequest& full_wallet_request) { } DCHECK_EQ(NO_PENDING_REQUEST, request_type_); - DCHECK(pending_request_body_.empty()); request_type_ = GET_FULL_WALLET; - pending_request_body_.SetString(kApiKeyKey, google_apis::GetAPIKey()); - pending_request_body_.SetString(kRiskParamsKey, delegate_->GetRiskData()); - pending_request_body_.SetString(kSelectedInstrumentIdKey, - full_wallet_request.instrument_id); - pending_request_body_.SetString(kSelectedAddressIdKey, - full_wallet_request.address_id); - pending_request_body_.SetString( + base::DictionaryValue request_dict; + request_dict.SetString(kApiKeyKey, google_apis::GetAPIKey()); + request_dict.SetString(kRiskParamsKey, delegate_->GetRiskData()); + request_dict.SetString(kSelectedInstrumentIdKey, + full_wallet_request.instrument_id); + request_dict.SetString(kSelectedAddressIdKey, full_wallet_request.address_id); + request_dict.SetString( kMerchantDomainKey, full_wallet_request.source_url.GetWithEmptyPath().spec()); - pending_request_body_.SetString(kGoogleTransactionIdKey, - full_wallet_request.google_transaction_id); - pending_request_body_.SetString( - kFeatureKey, - DialogTypeToFeatureString(delegate_->GetDialogType())); + request_dict.SetString(kGoogleTransactionIdKey, + full_wallet_request.google_transaction_id); + request_dict.SetString(kFeatureKey, + DialogTypeToFeatureString(delegate_->GetDialogType())); scoped_ptr<base::ListValue> risk_capabilities_list(new base::ListValue()); for (std::vector<RiskCapability>::const_iterator it = @@ -337,47 +353,41 @@ void WalletClient::GetFullWallet(const FullWalletRequest& full_wallet_request) { ++it) { risk_capabilities_list->AppendString(RiskCapabilityToString(*it)); } - pending_request_body_.Set(kRiskCapabilitiesKey, - risk_capabilities_list.release()); + request_dict.Set(kRiskCapabilitiesKey, risk_capabilities_list.release()); - crypto::RandBytes(&(one_time_pad_[0]), one_time_pad_.size()); - encryption_escrow_client_.EncryptOneTimePad(one_time_pad_); -} + std::string json_payload; + base::JSONWriter::Write(&request_dict, &json_payload); -void WalletClient::GetWalletItems(const GURL& source_url) { - if (HasRequestInProgress()) { - pending_requests_.push(base::Bind(&WalletClient::GetWalletItems, - base::Unretained(this), - source_url)); - return; - } + crypto::RandBytes(&(one_time_pad_[0]), one_time_pad_.size()); - DCHECK_EQ(NO_PENDING_REQUEST, request_type_); - request_type_ = GET_WALLET_ITEMS; + size_t num_bits = one_time_pad_.size() * 8; + DCHECK_LE(num_bits, kMaxBits); + DCHECK_GE(num_bits, kMinBits); - base::DictionaryValue request_dict; - request_dict.SetString(kApiKeyKey, google_apis::GetAPIKey()); - request_dict.SetString(kMerchantDomainKey, - source_url.GetWithEmptyPath().spec()); - - std::string post_body; - base::JSONWriter::Write(&request_dict, &post_body); + std::string post_body = base::StringPrintf( + kGetFullWalletRequestFormat, + net::EscapeUrlEncodedData(json_payload, true).c_str(), + base::HexEncode(&num_bits, 1).c_str(), + base::HexEncode(&(one_time_pad_[0]), one_time_pad_.size()).c_str()); - MakeWalletRequest(GetGetWalletItemsUrl(), post_body); + MakeWalletRequest(GetGetFullWalletUrl(), post_body, kFormEncodedMimeType); } -void WalletClient::SaveAddress(const Address& shipping_address, - const GURL& source_url) { +void WalletClient::SaveToWallet(scoped_ptr<Instrument> instrument, + scoped_ptr<Address> address, + const GURL& source_url) { + DCHECK(instrument || address); if (HasRequestInProgress()) { - pending_requests_.push(base::Bind(&WalletClient::SaveAddress, + pending_requests_.push(base::Bind(&WalletClient::SaveToWallet, base::Unretained(this), - shipping_address, + base::Passed(&instrument), + base::Passed(&address), source_url)); return; } DCHECK_EQ(NO_PENDING_REQUEST, request_type_); - request_type_ = SAVE_ADDRESS; + request_type_ = SAVE_TO_WALLET; base::DictionaryValue request_dict; request_dict.SetString(kApiKeyKey, google_apis::GetAPIKey()); @@ -385,80 +395,97 @@ void WalletClient::SaveAddress(const Address& shipping_address, request_dict.SetString(kMerchantDomainKey, source_url.GetWithEmptyPath().spec()); - request_dict.Set(kShippingAddressKey, - shipping_address.ToDictionaryWithID().release()); - - std::string post_body; - base::JSONWriter::Write(&request_dict, &post_body); + std::string primary_account_number; + std::string card_verification_number; + if (instrument) { + primary_account_number = net::EscapeUrlEncodedData( + UTF16ToUTF8(instrument->primary_account_number()), true); + card_verification_number = net::EscapeUrlEncodedData( + UTF16ToUTF8(instrument->card_verification_number()), true); + + if (instrument->object_id().empty()) { + request_dict.Set(kInstrumentKey, instrument->ToDictionary().release()); + request_dict.SetString(kInstrumentPhoneNumberKey, + instrument->address()->phone_number()); + } else { + DCHECK(instrument->address() || + (instrument->expiration_month() > 0 && + instrument->expiration_year() > 0)); + + request_dict.SetString(kUpgradedInstrumentIdKey, + instrument->object_id()); + + if (instrument->address()) { + request_dict.SetString(kInstrumentPhoneNumberKey, + instrument->address()->phone_number()); + request_dict.Set( + kUpgradedBillingAddressKey, + instrument->address()->ToDictionaryWithoutID().release()); + } - MakeWalletRequest(GetSaveToWalletUrl(), post_body); -} + if (instrument->expiration_month() > 0 && + instrument->expiration_year() > 0) { + DCHECK(!instrument->card_verification_number().empty()); + request_dict.SetInteger(kInstrumentExpMonthKey, + instrument->expiration_month()); + request_dict.SetInteger(kInstrumentExpYearKey, + instrument->expiration_year()); + } -void WalletClient::SaveInstrument( - const Instrument& instrument, - const std::string& obfuscated_gaia_id, - const GURL& source_url) { - if (HasRequestInProgress()) { - pending_requests_.push(base::Bind(&WalletClient::SaveInstrument, - base::Unretained(this), - instrument, - obfuscated_gaia_id, - source_url)); - return; + if (request_dict.HasKey(kInstrumentKey)) + request_dict.SetString(kInstrumentType, "CREDIT_CARD"); + } + } + if (address) { + request_dict.Set(kShippingAddressKey, + address->ToDictionaryWithID().release()); } - DCHECK_EQ(NO_PENDING_REQUEST, request_type_); - DCHECK(pending_request_body_.empty()); - request_type_ = SAVE_INSTRUMENT; - - pending_request_body_.SetString(kApiKeyKey, google_apis::GetAPIKey()); - pending_request_body_.SetString(kRiskParamsKey, delegate_->GetRiskData()); - pending_request_body_.SetString(kMerchantDomainKey, - source_url.GetWithEmptyPath().spec()); - - pending_request_body_.Set(kInstrumentKey, - instrument.ToDictionary().release()); - pending_request_body_.SetString(kInstrumentPhoneNumberKey, - instrument.address().phone_number()); + std::string json_payload; + base::JSONWriter::Write(&request_dict, &json_payload); - encryption_escrow_client_.EscrowInstrumentInformation(instrument, - obfuscated_gaia_id); + if (!card_verification_number.empty()) { + std::string post_body; + if (!primary_account_number.empty()) { + post_body = base::StringPrintf( + kEscrowNewInstrumentFormat, + net::EscapeUrlEncodedData(json_payload, true).c_str(), + card_verification_number.c_str(), + primary_account_number.c_str()); + } else { + post_body = base::StringPrintf( + kEscrowCardVerificationNumberFormat, + net::EscapeUrlEncodedData(json_payload, true).c_str(), + card_verification_number.c_str()); + } + MakeWalletRequest(GetSaveToWalletUrl(), post_body, kFormEncodedMimeType); + } else { + MakeWalletRequest(GetSaveToWalletNoEscrowUrl(), + json_payload, + kJsonMimeType); + } } -void WalletClient::SaveInstrumentAndAddress( - const Instrument& instrument, - const Address& address, - const std::string& obfuscated_gaia_id, - const GURL& source_url) { +void WalletClient::GetWalletItems(const GURL& source_url) { if (HasRequestInProgress()) { - pending_requests_.push(base::Bind(&WalletClient::SaveInstrumentAndAddress, + pending_requests_.push(base::Bind(&WalletClient::GetWalletItems, base::Unretained(this), - instrument, - address, - obfuscated_gaia_id, source_url)); return; } DCHECK_EQ(NO_PENDING_REQUEST, request_type_); - DCHECK(pending_request_body_.empty()); - request_type_ = SAVE_INSTRUMENT_AND_ADDRESS; - - pending_request_body_.SetString(kApiKeyKey, google_apis::GetAPIKey()); - pending_request_body_.SetString(kRiskParamsKey, delegate_->GetRiskData()); - pending_request_body_.SetString(kMerchantDomainKey, - source_url.GetWithEmptyPath().spec()); + request_type_ = GET_WALLET_ITEMS; - pending_request_body_.Set(kInstrumentKey, - instrument.ToDictionary().release()); - pending_request_body_.SetString(kInstrumentPhoneNumberKey, - instrument.address().phone_number()); + base::DictionaryValue request_dict; + request_dict.SetString(kApiKeyKey, google_apis::GetAPIKey()); + request_dict.SetString(kMerchantDomainKey, + source_url.GetWithEmptyPath().spec()); - pending_request_body_.Set(kShippingAddressKey, - address.ToDictionaryWithID().release()); + std::string post_body; + base::JSONWriter::Write(&request_dict, &post_body); - encryption_escrow_client_.EscrowInstrumentInformation(instrument, - obfuscated_gaia_id); + MakeWalletRequest(GetGetWalletItemsUrl(), post_body, kJsonMimeType); } void WalletClient::SendAutocheckoutStatus( @@ -504,116 +531,14 @@ void WalletClient::SendAutocheckoutStatus( std::string post_body; base::JSONWriter::Write(&request_dict, &post_body); - MakeWalletRequest(GetSendStatusUrl(), post_body); -} - -void WalletClient::UpdateAddress(const Address& address, - const GURL& source_url) { - if (HasRequestInProgress()) { - pending_requests_.push(base::Bind(&WalletClient::UpdateAddress, - base::Unretained(this), - address, - source_url)); - return; - } - - DCHECK_EQ(NO_PENDING_REQUEST, request_type_); - request_type_ = UPDATE_ADDRESS; - - base::DictionaryValue request_dict; - request_dict.SetString(kApiKeyKey, google_apis::GetAPIKey()); - request_dict.SetString(kRiskParamsKey, delegate_->GetRiskData()); - request_dict.SetString(kMerchantDomainKey, - source_url.GetWithEmptyPath().spec()); - - request_dict.Set(kShippingAddressKey, - address.ToDictionaryWithID().release()); - - std::string post_body; - base::JSONWriter::Write(&request_dict, &post_body); - - MakeWalletRequest(GetSaveToWalletUrl(), post_body); -} - -void WalletClient::UpdateInstrument( - const UpdateInstrumentRequest& update_instrument_request, - scoped_ptr<Address> billing_address) { - if (HasRequestInProgress()) { - pending_requests_.push(base::Bind(&WalletClient::UpdateInstrument, - base::Unretained(this), - update_instrument_request, - base::Passed(&billing_address))); - return; - } - - DCHECK_EQ(NO_PENDING_REQUEST, request_type_); - DCHECK(pending_request_body_.empty()); - DCHECK(update_instrument_request.card_verification_number.empty() == - update_instrument_request.obfuscated_gaia_id.empty()); - DCHECK(billing_address || - (update_instrument_request.expiration_month > 0 && - update_instrument_request.expiration_year > 0)); - - request_type_ = UPDATE_INSTRUMENT; - - base::DictionaryValue* active_request_body; - base::DictionaryValue request_dict; - if (update_instrument_request.card_verification_number.empty()) - active_request_body = &request_dict; - else - active_request_body = &pending_request_body_; - - active_request_body->SetString(kApiKeyKey, google_apis::GetAPIKey()); - active_request_body->SetString(kRiskParamsKey, delegate_->GetRiskData()); - active_request_body->SetString( - kMerchantDomainKey, - update_instrument_request.source_url.GetWithEmptyPath().spec()); - - active_request_body->SetString(kUpgradedInstrumentIdKey, - update_instrument_request.instrument_id); - - if (billing_address) { - active_request_body->SetString(kInstrumentPhoneNumberKey, - billing_address->phone_number()); - active_request_body->Set( - kUpgradedBillingAddressKey, - billing_address->ToDictionaryWithoutID().release()); - } - - if (update_instrument_request.expiration_month > 0 && - update_instrument_request.expiration_year > 0) { - DCHECK(!update_instrument_request.card_verification_number.empty()); - active_request_body->SetInteger( - kInstrumentExpMonthKey, - update_instrument_request.expiration_month); - active_request_body->SetInteger(kInstrumentExpYearKey, - update_instrument_request.expiration_year); - } - - if (active_request_body->HasKey(kInstrumentKey)) - active_request_body->SetString(kInstrumentType, "CREDIT_CARD"); - - if (update_instrument_request.card_verification_number.empty()) { - std::string post_body; - base::JSONWriter::Write(active_request_body, &post_body); - MakeWalletRequest(GetSaveToWalletUrl(), post_body); - } else { - encryption_escrow_client_.EscrowCardVerificationNumber( - update_instrument_request.card_verification_number, - update_instrument_request.obfuscated_gaia_id); - } + MakeWalletRequest(GetSendStatusUrl(), post_body, kJsonMimeType); } bool WalletClient::HasRequestInProgress() const { - // |SaveInstrument*()| and |UpdateInstrument()| methods don't set |request_| - // until sensitive info has been escrowed, so this class is considered to have - // a request in progress if |encryption_escrow_client_| is working as well. - return request_ || encryption_escrow_client_.HasRequestInProgress(); + return request_; } void WalletClient::CancelRequests() { - encryption_escrow_client_.CancelRequest(); - pending_request_body_.Clear(); request_.reset(); request_type_ = NO_PENDING_REQUEST; while (!pending_requests_.empty()) { @@ -653,18 +578,19 @@ void WalletClient::DoAcceptLegalDocuments( std::string post_body; base::JSONWriter::Write(&request_dict, &post_body); - MakeWalletRequest(GetAcceptLegalDocumentsUrl(), post_body); + MakeWalletRequest(GetAcceptLegalDocumentsUrl(), post_body, kJsonMimeType); } void WalletClient::MakeWalletRequest(const GURL& url, - const std::string& post_body) { + const std::string& post_body, + const std::string& mime_type) { DCHECK(!HasRequestInProgress()); request_.reset(net::URLFetcher::Create( 0, url, net::URLFetcher::POST, this)); request_->SetRequestContext(context_getter_.get()); VLOG(1) << "Making request to " << url << " with post_body=" << post_body; - request_->SetUploadData(kJsonMimeType, post_body); + request_->SetUploadData(mime_type, post_body); request_->AddExtraRequestHeader("Authorization: GoogleLogin auth=" + delegate_->GetWalletCookieValue()); DVLOG(1) << "Setting authorization header value to " @@ -793,44 +719,7 @@ void WalletClient::OnURLFetchComplete( break; } - case SAVE_ADDRESS: { - std::string shipping_address_id; - std::vector<RequiredAction> required_actions; - GetRequiredActionsForSaveToWallet(*response_dict, &required_actions); - std::vector<FormFieldError> form_errors; - GetFormFieldErrors(*response_dict, &form_errors); - if (response_dict->GetString(kShippingAddressIdKey, - &shipping_address_id) || - !required_actions.empty()) { - LogRequiredActions(required_actions); - delegate_->OnDidSaveAddress(shipping_address_id, - required_actions, - form_errors); - } else { - HandleMalformedResponse(); - } - break; - } - - case SAVE_INSTRUMENT: { - std::string instrument_id; - std::vector<RequiredAction> required_actions; - GetRequiredActionsForSaveToWallet(*response_dict, &required_actions); - std::vector<FormFieldError> form_errors; - GetFormFieldErrors(*response_dict, &form_errors); - if (response_dict->GetString(kInstrumentIdKey, &instrument_id) || - !required_actions.empty()) { - LogRequiredActions(required_actions); - delegate_->OnDidSaveInstrument(instrument_id, - required_actions, - form_errors); - } else { - HandleMalformedResponse(); - } - break; - } - - case SAVE_INSTRUMENT_AND_ADDRESS: { + case SAVE_TO_WALLET: { std::string instrument_id; response_dict->GetString(kInstrumentIdKey, &instrument_id); std::string shipping_address_id; @@ -840,51 +729,15 @@ void WalletClient::OnURLFetchComplete( GetRequiredActionsForSaveToWallet(*response_dict, &required_actions); std::vector<FormFieldError> form_errors; GetFormFieldErrors(*response_dict, &form_errors); - if ((!instrument_id.empty() && !shipping_address_id.empty()) || - !required_actions.empty()) { - LogRequiredActions(required_actions); - delegate_->OnDidSaveInstrumentAndAddress(instrument_id, - shipping_address_id, - required_actions, - form_errors); - } else { + if (instrument_id.empty() && shipping_address_id.empty() && + required_actions.empty()) { HandleMalformedResponse(); - } - break; - } - - case UPDATE_ADDRESS: { - std::string address_id; - std::vector<RequiredAction> required_actions; - GetRequiredActionsForSaveToWallet(*response_dict, &required_actions); - std::vector<FormFieldError> form_errors; - GetFormFieldErrors(*response_dict, &form_errors); - if (response_dict->GetString(kShippingAddressIdKey, &address_id) || - !required_actions.empty()) { - LogRequiredActions(required_actions); - delegate_->OnDidUpdateAddress(address_id, - required_actions, - form_errors); } else { - HandleMalformedResponse(); - } - break; - } - - case UPDATE_INSTRUMENT: { - std::string instrument_id; - std::vector<RequiredAction> required_actions; - GetRequiredActionsForSaveToWallet(*response_dict, &required_actions); - std::vector<FormFieldError> form_errors; - GetFormFieldErrors(*response_dict, &form_errors); - if (response_dict->GetString(kInstrumentIdKey, &instrument_id) || - !required_actions.empty()) { LogRequiredActions(required_actions); - delegate_->OnDidUpdateInstrument(instrument_id, - required_actions, - form_errors); - } else { - HandleMalformedResponse(); + delegate_->OnDidSaveToWallet(instrument_id, + shipping_address_id, + required_actions, + form_errors); } break; } @@ -951,64 +804,6 @@ void WalletClient::HandleWalletError(WalletClient::ErrorType error_type) { delegate_->GetDialogType(), ErrorTypeToUmaMetric(error_type)); } -void WalletClient::OnDidEncryptOneTimePad( - const std::string& encrypted_one_time_pad, - const std::string& session_material) { - DCHECK_EQ(GET_FULL_WALLET, request_type_); - pending_request_body_.SetString(kEncryptedOtpKey, encrypted_one_time_pad); - pending_request_body_.SetString(kSessionMaterialKey, session_material); - - std::string post_body; - base::JSONWriter::Write(&pending_request_body_, &post_body); - pending_request_body_.Clear(); - - MakeWalletRequest(GetGetFullWalletUrl(), post_body); -} - -void WalletClient::OnDidEscrowInstrumentInformation( - const std::string& escrow_handle) { - DCHECK(request_type_ == SAVE_INSTRUMENT || - request_type_ == SAVE_INSTRUMENT_AND_ADDRESS); - - pending_request_body_.SetString(kInstrumentEscrowHandleKey, escrow_handle); - - std::string post_body; - base::JSONWriter::Write(&pending_request_body_, &post_body); - pending_request_body_.Clear(); - - MakeWalletRequest(GetSaveToWalletUrl(), post_body); -} - -void WalletClient::OnDidEscrowCardVerificationNumber( - const std::string& escrow_handle) { - DCHECK(request_type_ == AUTHENTICATE_INSTRUMENT || - request_type_ == UPDATE_INSTRUMENT); - pending_request_body_.SetString(kInstrumentEscrowHandleKey, escrow_handle); - - std::string post_body; - base::JSONWriter::Write(&pending_request_body_, &post_body); - pending_request_body_.Clear(); - - if (request_type_ == AUTHENTICATE_INSTRUMENT) - MakeWalletRequest(GetAuthenticateInstrumentUrl(), post_body); - else - MakeWalletRequest(GetSaveToWalletUrl(), post_body); -} - -void WalletClient::OnDidMakeRequest() { - delegate_->GetMetricLogger().LogWalletErrorMetric( - delegate_->GetDialogType(), - AutofillMetrics::WALLET_ERROR_BASELINE_ISSUED_REQUEST); -} - -void WalletClient::OnNetworkError() { - HandleWalletError(NETWORK_ERROR); -} - -void WalletClient::OnMalformedResponse() { - HandleWalletError(MALFORMED_RESPONSE); -} - // Logs an UMA metric for each of the |required_actions|. void WalletClient::LogRequiredActions( const std::vector<RequiredAction>& required_actions) const { @@ -1030,18 +825,10 @@ AutofillMetrics::WalletApiCallMetric WalletClient::RequestTypeToUmaMetric( return AutofillMetrics::GET_FULL_WALLET; case GET_WALLET_ITEMS: return AutofillMetrics::GET_WALLET_ITEMS; - case SAVE_ADDRESS: - return AutofillMetrics::SAVE_ADDRESS; - case SAVE_INSTRUMENT: - return AutofillMetrics::SAVE_INSTRUMENT; - case SAVE_INSTRUMENT_AND_ADDRESS: - return AutofillMetrics::SAVE_INSTRUMENT_AND_ADDRESS; + case SAVE_TO_WALLET: + return AutofillMetrics::SAVE_TO_WALLET; case SEND_STATUS: return AutofillMetrics::SEND_STATUS; - case UPDATE_ADDRESS: - return AutofillMetrics::UPDATE_ADDRESS; - case UPDATE_INSTRUMENT: - return AutofillMetrics::UPDATE_INSTRUMENT; case NO_PENDING_REQUEST: NOTREACHED(); return AutofillMetrics::UNKNOWN_API_CALL; diff --git a/components/autofill/content/browser/wallet/wallet_client.h b/components/autofill/content/browser/wallet/wallet_client.h index 1785cf6..486698c 100644 --- a/components/autofill/content/browser/wallet/wallet_client.h +++ b/components/autofill/content/browser/wallet/wallet_client.h @@ -14,8 +14,6 @@ #include "base/time/time.h" #include "base/values.h" #include "components/autofill/content/browser/autocheckout_statistic.h" -#include "components/autofill/content/browser/wallet/encryption_escrow_client.h" -#include "components/autofill/content/browser/wallet/encryption_escrow_client_observer.h" #include "components/autofill/content/browser/wallet/full_wallet.h" #include "components/autofill/content/browser/wallet/wallet_items.h" #include "components/autofill/core/browser/autofill_manager_delegate.h" @@ -42,15 +40,15 @@ class WalletClientDelegate; // the user's behalf. The normal flow for using this class is as follows: // 1) GetWalletItems should be called to retrieve the user's Wallet. // a) If the user does not have a Wallet, they must AcceptLegalDocuments and -// SaveInstrumentAndAddress before continuing. +// SaveToWallet to set up their account before continuing. // b) If the user has not accepted the most recent legal documents for // Wallet, they must AcceptLegalDocuments. // 2) The user then chooses what instrument and shipping address to use for the // current transaction. // a) If they choose an instrument with a zip code only address, the billing -// address will need to be updated using UpdateInstrument. +// address will need to be updated using SaveToWallet. // b) The user may also choose to add a new instrument or address using -// SaveAddress, SaveInstrument, or SaveInstrumentAndAddress. +// SaveToWallet. // 3) Once the user has selected the backing instrument and shipping address // for this transaction, a FullWallet with the fronting card is generated // using GetFullWallet. @@ -65,9 +63,7 @@ class WalletClientDelegate; // GetWalletItems(), the request will be queued and started later. Queued // requests start in the order they were received. -class WalletClient - : public net::URLFetcherDelegate, - public EncryptionEscrowClientObserver { +class WalletClient : public net::URLFetcherDelegate { public: // The Risk challenges supported by users of WalletClient. enum RiskCapability { @@ -130,33 +126,6 @@ class WalletClient DISALLOW_ASSIGN(FullWalletRequest); }; - struct UpdateInstrumentRequest { - public: - UpdateInstrumentRequest(const std::string& instrument_id, - const GURL& source_url); - ~UpdateInstrumentRequest(); - - // The id of the instrument being modified. - std::string instrument_id; - - // The new expiration date. If these are set, |card_verification_number| and - // |obfuscated_gaia_id| must be provided. - int expiration_month; - int expiration_year; - - // Used to authenticate the card the user is modifying. - std::string card_verification_number; - - // Used to key the escrow of |card_verification_number|. - std::string obfuscated_gaia_id; - - // The url this call is initiated from. - GURL source_url; - - private: - DISALLOW_ASSIGN(UpdateInstrumentRequest); - }; - // |context_getter| is reference counted so it has no lifetime or ownership // requirements. |delegate| must outlive |this|. WalletClient(net::URLRequestContextGetter* context_getter, @@ -185,25 +154,17 @@ class WalletClient // complete. Used to respond to Risk challenges. virtual void AuthenticateInstrument( const std::string& instrument_id, - const std::string& card_verification_number, - const std::string& obfuscated_gaia_id); + const std::string& card_verification_number); // GetFullWallet retrieves the a FullWallet for the user. virtual void GetFullWallet(const FullWalletRequest& full_wallet_request); - // SaveAddress saves a new shipping address. - virtual void SaveAddress(const Address& address, const GURL& source_url); - - // SaveInstrument saves a new instrument. - virtual void SaveInstrument(const Instrument& instrument, - const std::string& obfuscated_gaia_id, - const GURL& source_url); - - // SaveInstrumentAndAddress saves a new instrument and address. - virtual void SaveInstrumentAndAddress(const Instrument& instrument, - const Address& shipping_address, - const std::string& obfuscated_gaia_id, - const GURL& source_url); + // Saves the data in |instrument| and/or |address| to Wallet. |instrument| + // does not have to be complete if its being used to update an existing + // instrument, like in the case of expiration date or address only updates. + virtual void SaveToWallet(scoped_ptr<Instrument> instrument, + scoped_ptr<Address> address, + const GURL& source_url); // SendAutocheckoutStatus is used for tracking the success of Autocheckout // flows. |status| is the result of the flow, |source_url| is the domain @@ -216,15 +177,6 @@ class WalletClient const std::vector<AutocheckoutStatistic>& latency_statistics, const std::string& google_transaction_id); - // UpdateAddress updates Online Wallet with the data in |address|. - virtual void UpdateAddress(const Address& address, const GURL& source_url); - - // Updates Online Wallet with the data in |update_instrument_request| and, if - // it's provided, |billing_address|. - virtual void UpdateInstrument( - const UpdateInstrumentRequest& update_instrument_request, - scoped_ptr<Address> billing_address); - bool HasRequestInProgress() const; // Cancels and clears the current |request_| and |pending_requests_| (if any). @@ -240,12 +192,8 @@ class WalletClient AUTHENTICATE_INSTRUMENT, GET_FULL_WALLET, GET_WALLET_ITEMS, - SAVE_ADDRESS, - SAVE_INSTRUMENT, - SAVE_INSTRUMENT_AND_ADDRESS, + SAVE_TO_WALLET, SEND_STATUS, - UPDATE_ADDRESS, - UPDATE_INSTRUMENT, }; // Like AcceptLegalDocuments, but takes a vector of document ids. @@ -254,9 +202,11 @@ class WalletClient const std::string& google_transaction_id, const GURL& source_url); - // Posts |post_body| to |url| and notifies |delegate_| when the request is - // complete. - void MakeWalletRequest(const GURL& url, const std::string& post_body); + // Posts |post_body| to |url| with content type |mime_type| and notifies + // |delegate_| when the request is complete. + void MakeWalletRequest(const GURL& url, + const std::string& post_body, + const std::string& mime_type); // Performs bookkeeping tasks for any invalid requests. void HandleMalformedResponse(); @@ -269,18 +219,6 @@ class WalletClient // net::URLFetcherDelegate: virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE; - // EncryptionEscrowClientObserver: - virtual void OnDidEncryptOneTimePad( - const std::string& encrypted_one_time_pad, - const std::string& session_material) OVERRIDE; - virtual void OnDidEscrowInstrumentInformation( - const std::string& escrow_handle) OVERRIDE; - virtual void OnDidEscrowCardVerificationNumber( - const std::string& escrow_handle) OVERRIDE; - virtual void OnDidMakeRequest() OVERRIDE; - virtual void OnNetworkError() OVERRIDE; - virtual void OnMalformedResponse() OVERRIDE; - // Logs an UMA metric for each of the |required_actions|. void LogRequiredActions( const std::vector<RequiredAction>& required_actions) const; @@ -307,18 +245,9 @@ class WalletClient // The one time pad used for GetFullWallet encryption. std::vector<uint8> one_time_pad_; - // GetFullWallet requests and requests that alter instruments rely on requests - // made through the |encryption_escrow_client_| finishing first. The request - // body is saved here while that those requests are in flight. - base::DictionaryValue pending_request_body_; - // Requests that are waiting to be run. std::queue<base::Closure> pending_requests_; - // This client is repsonsible for making encryption and escrow calls to Online - // Wallet. - EncryptionEscrowClient encryption_escrow_client_; - // When the current request started. Used to track client side latency. base::Time request_started_timestamp_; diff --git a/components/autofill/content/browser/wallet/wallet_client_delegate.h b/components/autofill/content/browser/wallet/wallet_client_delegate.h index 2cc7bab..675ce0a 100644 --- a/components/autofill/content/browser/wallet/wallet_client_delegate.h +++ b/components/autofill/content/browser/wallet/wallet_client_delegate.h @@ -61,55 +61,17 @@ class WalletClientDelegate { // transferred to implementer of this interface. virtual void OnDidGetWalletItems(scoped_ptr<WalletItems> wallet_items) = 0; - // Called when a SaveAddress request finishes successfully. |address_id| can - // be used in subsequent GetFullWallet calls. |required_actions| is populated - // if there was a validation error with the data being saved. - // |form_field_errors| is populated with the actual form fields that are - // failing validation. - virtual void OnDidSaveAddress( - const std::string& address_id, - const std::vector<RequiredAction>& required_actions, - const std::vector<FormFieldError>& form_field_errors) = 0; - - // Called when a SaveInstrument request finishes sucessfully. |instrument_id| - // can be used in subsequent GetFullWallet calls. |required_actions| is - // populated if there was a validation error with the data being saved. - // |form_field_errors| is populated with the actual form fields that are - // failing validation. - virtual void OnDidSaveInstrument( - const std::string& instrument_id, - const std::vector<RequiredAction>& required_actions, - const std::vector<FormFieldError>& form_field_errors) = 0; - - // Called when a SaveInstrumentAndAddress request finishes succesfully. + // Called when a SaveToWallet request finishes succesfully. // |instrument_id| and |address_id| can be used in subsequent // GetFullWallet calls. |required_actions| is populated if there was a // validation error with the data being saved. |form_field_errors| is // populated with the actual form fields that are failing validation. - virtual void OnDidSaveInstrumentAndAddress( + virtual void OnDidSaveToWallet( const std::string& instrument_id, const std::string& address_id, const std::vector<RequiredAction>& required_actions, const std::vector<FormFieldError>& form_field_errors) = 0; - // Called when an UpdateAddress request finishes successfully. - // |required_actions| is populated if there was a validation error with the - // data being saved. |form_field_errors| is populated with the actual form - // fields that are failing validation. - virtual void OnDidUpdateAddress( - const std::string& address_id, - const std::vector<RequiredAction>& required_actions, - const std::vector<FormFieldError>& form_field_errors) = 0; - - // Called when an UpdateInstrument request finishes successfully. - // |required_actions| is populated if there was a validation error with the - // data being saved. |form_field_errors| is populated with the actual form - // fields that are failing validation. - virtual void OnDidUpdateInstrument( - const std::string& instrument_id, - const std::vector<RequiredAction>& required_actions, - const std::vector<FormFieldError>& form_field_errors) = 0; - // Called when a request fails. virtual void OnWalletError(WalletClient::ErrorType error_type) = 0; diff --git a/components/autofill/content/browser/wallet/wallet_client_unittest.cc b/components/autofill/content/browser/wallet/wallet_client_unittest.cc index a148d44..6536c3e 100644 --- a/components/autofill/content/browser/wallet/wallet_client_unittest.cc +++ b/components/autofill/content/browser/wallet/wallet_client_unittest.cc @@ -7,6 +7,7 @@ #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "base/strings/string_number_conversions.h" +#include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "base/values.h" #include "components/autofill/content/browser/autocheckout_steps.h" @@ -20,6 +21,7 @@ #include "components/autofill/core/common/autocheckout_status.h" #include "content/public/test/test_browser_context.h" #include "content/public/test/test_browser_thread.h" +#include "net/base/escape.h" #include "net/base/net_errors.h" #include "net/http/http_request_headers.h" #include "net/http/http_status_code.h" @@ -211,16 +213,6 @@ const char kSaveInstrumentAndAddressWithRequiredActionsValidResponse[] = " ]" "}"; -const char kSaveInstrumentAndAddressMissingAddressResponse[] = - "{" - " \"instrument_id\":\"instrument_id\"" - "}"; - -const char kSaveInstrumentAndAddressMissingInstrumentResponse[] = - "{" - " \"shipping_address_id\":\"saved_address_id\"" - "}"; - const char kUpdateInstrumentValidResponse[] = "{" " \"instrument_id\":\"instrument_id\"" @@ -316,21 +308,18 @@ const char kAcceptLegalDocumentsValidRequest[] = const char kAuthenticateInstrumentValidRequest[] = "{" - "\"instrument_escrow_handle\":\"escrow_handle\"," "\"instrument_id\":\"instrument_id\"," "\"risk_params\":\"risky business\"" "}"; const char kGetFullWalletValidRequest[] = "{" - "\"encrypted_otp\":\"encrypted_one_time_pad\"," "\"feature\":\"REQUEST_AUTOCOMPLETE\"," "\"google_transaction_id\":\"google_transaction_id\"," "\"merchant_domain\":\"https://example.com/\"," "\"risk_params\":\"risky business\"," "\"selected_address_id\":\"shipping_address_id\"," "\"selected_instrument_id\":\"instrument_id\"," - "\"session_material\":\"session_material\"," "\"supported_risk_challenge\":" "[" "]" @@ -338,14 +327,12 @@ const char kGetFullWalletValidRequest[] = const char kGetFullWalletWithRiskCapabilitesValidRequest[] = "{" - "\"encrypted_otp\":\"encrypted_one_time_pad\"," "\"feature\":\"REQUEST_AUTOCOMPLETE\"," "\"google_transaction_id\":\"google_transaction_id\"," "\"merchant_domain\":\"https://example.com/\"," "\"risk_params\":\"risky business\"," "\"selected_address_id\":\"shipping_address_id\"," "\"selected_instrument_id\":\"instrument_id\"," - "\"session_material\":\"session_material\"," "\"supported_risk_challenge\":" "[" "\"VERIFY_CVC\"" @@ -406,7 +393,6 @@ const char kSaveInstrumentValidRequest[] = "}," "\"type\":\"CREDIT_CARD\"" "}," - "\"instrument_escrow_handle\":\"escrow_handle\"," "\"instrument_phone_number\":\"phone_number\"," "\"merchant_domain\":\"https://example.com/\"," "\"risk_params\":\"risky business\"" @@ -438,7 +424,6 @@ const char kSaveInstrumentAndAddressValidRequest[] = "}," "\"type\":\"CREDIT_CARD\"" "}," - "\"instrument_escrow_handle\":\"escrow_handle\"," "\"instrument_phone_number\":\"phone_number\"," "\"merchant_domain\":\"https://example.com/\"," "\"risk_params\":\"risky business\"," @@ -532,38 +517,6 @@ const char kUpdateInstrumentAddressValidRequest[] = const char kUpdateInstrumentAddressWithNameChangeValidRequest[] = "{" - "\"instrument_escrow_handle\":\"escrow_handle\"," - "\"instrument_phone_number\":\"phone_number\"," - "\"merchant_domain\":\"https://example.com/\"," - "\"risk_params\":\"risky business\"," - "\"upgraded_billing_address\":" - "{" - "\"address_line\":" - "[" - "\"address_line_1\"," - "\"address_line_2\"" - "]," - "\"administrative_area_name\":\"admin_area_name\"," - "\"country_name_code\":\"US\"," - "\"locality_name\":\"locality_name\"," - "\"postal_code_number\":\"postal_code_number\"," - "\"recipient_name\":\"recipient_name\"" - "}," - "\"upgraded_instrument_id\":\"instrument_id\"" - "}"; - -const char kUpdateInstrumentAddressAndExpirationDateValidRequest[] = - "{" - "\"instrument\":" - "{" - "\"credit_card\":" - "{" - "\"exp_month\":12," - "\"exp_year\":2015" - "}," - "\"type\":\"CREDIT_CARD\"" - "}," - "\"instrument_escrow_handle\":\"escrow_handle\"," "\"instrument_phone_number\":\"phone_number\"," "\"merchant_domain\":\"https://example.com/\"," "\"risk_params\":\"risky business\"," @@ -590,11 +543,10 @@ const char kUpdateInstrumentExpirationDateValidRequest[] = "\"credit_card\":" "{" "\"exp_month\":12," - "\"exp_year\":2015" + "\"exp_year\":3000" "}," "\"type\":\"CREDIT_CARD\"" "}," - "\"instrument_escrow_handle\":\"escrow_handle\"," "\"merchant_domain\":\"https://example.com/\"," "\"risk_params\":\"risky business\"," "\"upgraded_instrument_id\":\"instrument_id\"" @@ -615,16 +567,6 @@ class MockAutofillMetrics : public AutofillMetrics { DISALLOW_COPY_AND_ASSIGN(MockAutofillMetrics); }; -enum EscrowRequestPresence { - HAS_ESCROW_REQUEST, - NO_ESCROW_REQUEST, -}; - -enum WalletRequestPresence { - HAS_WALLET_REQUEST, - NO_WALLET_REQUEST, -}; - class MockWalletClientDelegate : public WalletClientDelegate { public: MockWalletClientDelegate() @@ -669,27 +611,15 @@ class MockWalletClientDelegate : public WalletClientDelegate { DIALOG_TYPE_REQUEST_AUTOCOMPLETE, metric)).Times(1); } - void ExpectBaselineMetrics(EscrowRequestPresence escrow_request_presence, - WalletRequestPresence wallet_request_presence) { - int num_requests = 0; - if (escrow_request_presence == HAS_ESCROW_REQUEST) - ++num_requests; - if (wallet_request_presence == HAS_WALLET_REQUEST) - ++num_requests; - - EXPECT_GT(num_requests, 0); - + void ExpectBaselineMetrics() { EXPECT_CALL( metric_logger_, LogWalletErrorMetric( DIALOG_TYPE_REQUEST_AUTOCOMPLETE, AutofillMetrics::WALLET_ERROR_BASELINE_ISSUED_REQUEST)) - .Times(num_requests); - - if (wallet_request_presence == HAS_WALLET_REQUEST) { - ExpectWalletRequiredActionMetric( - AutofillMetrics::WALLET_REQUIRED_ACTION_BASELINE_ISSUED_REQUEST); - } + .Times(1); + ExpectWalletRequiredActionMetric( + AutofillMetrics::WALLET_REQUIRED_ACTION_BASELINE_ISSUED_REQUEST); } MockAutofillMetrics* metric_logger() { @@ -698,27 +628,11 @@ class MockWalletClientDelegate : public WalletClientDelegate { MOCK_METHOD0(OnDidAcceptLegalDocuments, void()); MOCK_METHOD1(OnDidAuthenticateInstrument, void(bool success)); - MOCK_METHOD3(OnDidSaveAddress, - void(const std::string& address_id, - const std::vector<RequiredAction>& required_actions, - const std::vector<FormFieldError>& form_field_errors)); - MOCK_METHOD3(OnDidSaveInstrument, - void(const std::string& instrument_id, - const std::vector<RequiredAction>& required_actions, - const std::vector<FormFieldError>& form_field_errors)); - MOCK_METHOD4(OnDidSaveInstrumentAndAddress, + MOCK_METHOD4(OnDidSaveToWallet, void(const std::string& instrument_id, const std::string& shipping_address_id, const std::vector<RequiredAction>& required_actions, const std::vector<FormFieldError>& form_field_errors)); - MOCK_METHOD3(OnDidUpdateAddress, - void(const std::string& address_id, - const std::vector<RequiredAction>& required_actions, - const std::vector<FormFieldError>& form_field_errors)); - MOCK_METHOD3(OnDidUpdateInstrument, - void(const std::string& instrument_id, - const std::vector<RequiredAction>& required_actions, - const std::vector<FormFieldError>& form_field_errors)); MOCK_METHOD1(OnWalletError, void(WalletClient::ErrorType error_type)); virtual void OnDidGetFullWallet(scoped_ptr<FullWallet> full_wallet) OVERRIDE { @@ -755,36 +669,34 @@ class WalletClientTest : public testing::Test { wallet_client_.reset(); } - std::string GetData(net::TestURLFetcher* fetcher) { - std::string data = fetcher->upload_data(); - scoped_ptr<Value> root(base::JSONReader::Read(data)); - - // If this is not a JSON dictionary, return plain text. - if (root.get() == NULL || !root->IsType(Value::TYPE_DICTIONARY)) - return data; + void VerifyAndFinishRequest(net::HttpStatusCode response_code, + const std::string& request_body, + const std::string& response_body) { + net::TestURLFetcher* fetcher = factory_.GetFetcherByID(0); + ASSERT_TRUE(fetcher); - // Remove api_key entry (to prevent accidental leak), return JSON as text. - DictionaryValue* dict = static_cast<DictionaryValue*>(root.get()); - dict->Remove("api_key", NULL); - base::JSONWriter::Write(dict, &data); - return data; - } + const std::string& upload_data = fetcher->upload_data(); + EXPECT_EQ(request_body, GetData(upload_data)); + net::HttpRequestHeaders request_headers; + fetcher->GetExtraRequestHeaders(&request_headers); + std::string auth_header_value; + EXPECT_TRUE(request_headers.GetHeader( + net::HttpRequestHeaders::kAuthorization, + &auth_header_value)); + EXPECT_EQ("GoogleLogin auth=gdToken", auth_header_value); - void DoEncryptionOrEscrowRequest(net::HttpStatusCode response_code, - const std::string& response_body) { - net::TestURLFetcher* encryption_fetcher = factory_.GetFetcherByID(1); - ASSERT_TRUE(encryption_fetcher); - encryption_fetcher->set_response_code(response_code); - encryption_fetcher->SetResponseString(response_body); - encryption_fetcher->delegate()->OnURLFetchComplete(encryption_fetcher); + fetcher->set_response_code(response_code); + fetcher->SetResponseString(response_body); + fetcher->delegate()->OnURLFetchComplete(fetcher); } - void VerifyAndFinishRequest(net::HttpStatusCode response_code, - const std::string& request_body, - const std::string& response_body) { + void VerifyAndFinishFormEncodedRequest(net::HttpStatusCode response_code, + const std::string& json_payload, + const std::string& response_body, + size_t expected_parameter_number) { net::TestURLFetcher* fetcher = factory_.GetFetcherByID(0); ASSERT_TRUE(fetcher); - EXPECT_EQ(request_body, GetData(fetcher)); + net::HttpRequestHeaders request_headers; fetcher->GetExtraRequestHeaders(&request_headers); std::string auth_header_value; @@ -792,6 +704,48 @@ class WalletClientTest : public testing::Test { net::HttpRequestHeaders::kAuthorization, &auth_header_value)); EXPECT_EQ("GoogleLogin auth=gdToken", auth_header_value); + + const std::string& upload_data = fetcher->upload_data(); + std::vector<std::pair<std::string, std::string> > tokens; + base::SplitStringIntoKeyValuePairs(upload_data, '=', '&', &tokens); + EXPECT_EQ(tokens.size(), expected_parameter_number); + + size_t num_params = 0U; + for (size_t i = 0; i < tokens.size(); ++i) { + const std::string& key = tokens[i].first; + const std::string& value = tokens[i].second; + + if (key == "request_content_type") { + EXPECT_EQ("application/json", value); + num_params++; + } + + if (key == "request") { + EXPECT_EQ(json_payload, + GetData( + net::UnescapeURLComponent( + value, net::UnescapeRule::URL_SPECIAL_CHARS | + net::UnescapeRule::REPLACE_PLUS_WITH_SPACE))); + num_params++; + } + + if (key == "cvn") { + EXPECT_EQ("123", value); + num_params++; + } + + if (key == "card_number") { + EXPECT_EQ("4444444444444448", value); + num_params++; + } + + if (key == "otp") { + EXPECT_FALSE(value.empty()); + num_params++; + } + } + EXPECT_EQ(expected_parameter_number, num_params); + fetcher->set_response_code(response_code); fetcher->SetResponseString(response_body); fetcher->delegate()->OnURLFetchComplete(fetcher); @@ -803,6 +757,21 @@ class WalletClientTest : public testing::Test { MockWalletClientDelegate delegate_; private: + std::string GetData(const std::string& upload_data) { + scoped_ptr<Value> root(base::JSONReader::Read(upload_data)); + + // If this is not a JSON dictionary, return plain text. + if (!root || !root->IsType(Value::TYPE_DICTIONARY)) + return upload_data; + + // Remove api_key entry (to prevent accidental leak), return JSON as text. + DictionaryValue* dict = static_cast<DictionaryValue*>(root.get()); + dict->Remove("api_key", NULL); + std::string clean_upload_data; + base::JSONWriter::Write(dict, &clean_upload_data); + return clean_upload_data; + } + net::TestURLFetcherFactory factory_; }; @@ -810,7 +779,7 @@ TEST_F(WalletClientTest, WalletError) { EXPECT_CALL(delegate_, OnWalletError( WalletClient::SERVICE_UNAVAILABLE)).Times(1); delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::SEND_STATUS, 1); - delegate_.ExpectBaselineMetrics(NO_ESCROW_REQUEST, HAS_WALLET_REQUEST); + delegate_.ExpectBaselineMetrics(); delegate_.ExpectWalletErrorMetric( AutofillMetrics::WALLET_SERVICE_UNAVAILABLE); @@ -828,7 +797,7 @@ TEST_F(WalletClientTest, WalletErrorResponseMissing) { EXPECT_CALL(delegate_, OnWalletError( WalletClient::UNKNOWN_ERROR)).Times(1); delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::SEND_STATUS, 1); - delegate_.ExpectBaselineMetrics(NO_ESCROW_REQUEST, HAS_WALLET_REQUEST); + delegate_.ExpectBaselineMetrics(); delegate_.ExpectWalletErrorMetric(AutofillMetrics::WALLET_UNKNOWN_ERROR); std::vector<AutocheckoutStatistic> statistics; @@ -844,7 +813,7 @@ TEST_F(WalletClientTest, WalletErrorResponseMissing) { TEST_F(WalletClientTest, NetworkFailureOnExpectedVoidResponse) { EXPECT_CALL(delegate_, OnWalletError(WalletClient::NETWORK_ERROR)).Times(1); delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::SEND_STATUS, 1); - delegate_.ExpectBaselineMetrics(NO_ESCROW_REQUEST, HAS_WALLET_REQUEST); + delegate_.ExpectBaselineMetrics(); delegate_.ExpectWalletErrorMetric(AutofillMetrics::WALLET_NETWORK_ERROR); std::vector<AutocheckoutStatistic> statistics; @@ -861,7 +830,7 @@ TEST_F(WalletClientTest, NetworkFailureOnExpectedResponse) { EXPECT_CALL(delegate_, OnWalletError(WalletClient::NETWORK_ERROR)).Times(1); delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::GET_WALLET_ITEMS, 1); - delegate_.ExpectBaselineMetrics(NO_ESCROW_REQUEST, HAS_WALLET_REQUEST); + delegate_.ExpectBaselineMetrics(); delegate_.ExpectWalletErrorMetric(AutofillMetrics::WALLET_NETWORK_ERROR); wallet_client_->GetWalletItems(GURL(kMerchantUrl)); @@ -873,7 +842,7 @@ TEST_F(WalletClientTest, NetworkFailureOnExpectedResponse) { TEST_F(WalletClientTest, RequestError) { EXPECT_CALL(delegate_, OnWalletError(WalletClient::BAD_REQUEST)).Times(1); delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::SEND_STATUS, 1); - delegate_.ExpectBaselineMetrics(NO_ESCROW_REQUEST, HAS_WALLET_REQUEST); + delegate_.ExpectBaselineMetrics(); delegate_.ExpectWalletErrorMetric(AutofillMetrics::WALLET_BAD_REQUEST); std::vector<AutocheckoutStatistic> statistics; @@ -888,7 +857,7 @@ TEST_F(WalletClientTest, RequestError) { TEST_F(WalletClientTest, GetFullWalletSuccess) { delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::GET_FULL_WALLET, 1); - delegate_.ExpectBaselineMetrics(HAS_ESCROW_REQUEST, HAS_WALLET_REQUEST); + delegate_.ExpectBaselineMetrics(); WalletClient::FullWalletRequest full_wallet_request( "instrument_id", @@ -898,18 +867,16 @@ TEST_F(WalletClientTest, GetFullWalletSuccess) { std::vector<WalletClient::RiskCapability>()); wallet_client_->GetFullWallet(full_wallet_request); - DoEncryptionOrEscrowRequest(net::HTTP_OK, - "session_material|encrypted_one_time_pad"); - - VerifyAndFinishRequest(net::HTTP_OK, - kGetFullWalletValidRequest, - kGetFullWalletValidResponse); + VerifyAndFinishFormEncodedRequest(net::HTTP_OK, + kGetFullWalletValidRequest, + kGetFullWalletValidResponse, + 3U); EXPECT_EQ(1U, delegate_.full_wallets_received()); } TEST_F(WalletClientTest, GetFullWalletWithRiskCapabilitesSuccess) { delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::GET_FULL_WALLET, 1); - delegate_.ExpectBaselineMetrics(HAS_ESCROW_REQUEST, HAS_WALLET_REQUEST); + delegate_.ExpectBaselineMetrics(); std::vector<WalletClient::RiskCapability> risk_capabilities; risk_capabilities.push_back(WalletClient::VERIFY_CVC); @@ -921,60 +888,20 @@ TEST_F(WalletClientTest, GetFullWalletWithRiskCapabilitesSuccess) { risk_capabilities); wallet_client_->GetFullWallet(full_wallet_request); - DoEncryptionOrEscrowRequest(net::HTTP_OK, - "session_material|encrypted_one_time_pad"); - - VerifyAndFinishRequest(net::HTTP_OK, - kGetFullWalletWithRiskCapabilitesValidRequest, - kGetFullWalletValidResponse); + VerifyAndFinishFormEncodedRequest( + net::HTTP_OK, + kGetFullWalletWithRiskCapabilitesValidRequest, + kGetFullWalletValidResponse, + 3U); EXPECT_EQ(1U, delegate_.full_wallets_received()); } -TEST_F(WalletClientTest, GetFullWalletEncryptionDown) { - EXPECT_CALL(delegate_, OnWalletError(WalletClient::NETWORK_ERROR)).Times(1); - delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::GET_FULL_WALLET, 0); - delegate_.ExpectBaselineMetrics(HAS_ESCROW_REQUEST, NO_WALLET_REQUEST); - delegate_.ExpectWalletErrorMetric(AutofillMetrics::WALLET_NETWORK_ERROR); - - WalletClient::FullWalletRequest full_wallet_request( - "instrument_id", - "shipping_address_id", - GURL(kMerchantUrl), - "google_transaction_id", - std::vector<WalletClient::RiskCapability>()); - wallet_client_->GetFullWallet(full_wallet_request); - - DoEncryptionOrEscrowRequest(net::HTTP_INTERNAL_SERVER_ERROR, std::string()); - - EXPECT_EQ(0U, delegate_.full_wallets_received()); -} - -TEST_F(WalletClientTest, GetFullWalletEncryptionMalformed) { - EXPECT_CALL(delegate_, - OnWalletError(WalletClient::MALFORMED_RESPONSE)).Times(1); - delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::GET_FULL_WALLET, 0); - delegate_.ExpectBaselineMetrics(HAS_ESCROW_REQUEST, NO_WALLET_REQUEST); - delegate_.ExpectWalletErrorMetric(AutofillMetrics::WALLET_MALFORMED_RESPONSE); - - WalletClient::FullWalletRequest full_wallet_request( - "instrument_id", - "shipping_address_id", - GURL(kMerchantUrl), - "google_transaction_id", - std::vector<WalletClient::RiskCapability>()); - wallet_client_->GetFullWallet(full_wallet_request); - - DoEncryptionOrEscrowRequest(net::HTTP_OK, - "session_material:encrypted_one_time_pad"); - - EXPECT_EQ(0U, delegate_.full_wallets_received()); -} TEST_F(WalletClientTest, GetFullWalletMalformedResponse) { EXPECT_CALL(delegate_, OnWalletError(WalletClient::MALFORMED_RESPONSE)).Times(1); delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::GET_FULL_WALLET, 1); - delegate_.ExpectBaselineMetrics(HAS_ESCROW_REQUEST, HAS_WALLET_REQUEST); + delegate_.ExpectBaselineMetrics(); delegate_.ExpectWalletErrorMetric(AutofillMetrics::WALLET_MALFORMED_RESPONSE); WalletClient::FullWalletRequest full_wallet_request( @@ -985,12 +912,10 @@ TEST_F(WalletClientTest, GetFullWalletMalformedResponse) { std::vector<WalletClient::RiskCapability>()); wallet_client_->GetFullWallet(full_wallet_request); - DoEncryptionOrEscrowRequest(net::HTTP_OK, - "session_material|encrypted_one_time_pad"); - - VerifyAndFinishRequest(net::HTTP_OK, - kGetFullWalletValidRequest, - kGetFullWalletInvalidResponse); + VerifyAndFinishFormEncodedRequest(net::HTTP_OK, + kGetFullWalletValidRequest, + kGetFullWalletInvalidResponse, + 3U); EXPECT_EQ(0U, delegate_.full_wallets_received()); } @@ -999,7 +924,7 @@ TEST_F(WalletClientTest, AcceptLegalDocuments) { delegate_.ExpectLogWalletApiCallDuration( AutofillMetrics::ACCEPT_LEGAL_DOCUMENTS, 1); - delegate_.ExpectBaselineMetrics(NO_ESCROW_REQUEST, HAS_WALLET_REQUEST); + delegate_.ExpectBaselineMetrics(); ScopedVector<WalletItems::LegalDocument> docs; base::DictionaryValue document; @@ -1026,17 +951,14 @@ TEST_F(WalletClientTest, AuthenticateInstrumentSucceeded) { delegate_.ExpectLogWalletApiCallDuration( AutofillMetrics::AUTHENTICATE_INSTRUMENT, 1); - delegate_.ExpectBaselineMetrics(HAS_ESCROW_REQUEST, HAS_WALLET_REQUEST); - - wallet_client_->AuthenticateInstrument("instrument_id", - "cvv", - "obfuscated_gaia_id"); + delegate_.ExpectBaselineMetrics(); - DoEncryptionOrEscrowRequest(net::HTTP_OK, "escrow_handle"); + wallet_client_->AuthenticateInstrument("instrument_id", "123"); - VerifyAndFinishRequest(net::HTTP_OK, - kAuthenticateInstrumentValidRequest, - kAuthenticateInstrumentSuccessResponse); + VerifyAndFinishFormEncodedRequest(net::HTTP_OK, + kAuthenticateInstrumentValidRequest, + kAuthenticateInstrumentSuccessResponse, + 3U); } TEST_F(WalletClientTest, AuthenticateInstrumentFailed) { @@ -1044,48 +966,14 @@ TEST_F(WalletClientTest, AuthenticateInstrumentFailed) { delegate_.ExpectLogWalletApiCallDuration( AutofillMetrics::AUTHENTICATE_INSTRUMENT, 1); - delegate_.ExpectBaselineMetrics(HAS_ESCROW_REQUEST, HAS_WALLET_REQUEST); - - wallet_client_->AuthenticateInstrument("instrument_id", - "cvv", - "obfuscated_gaia_id"); - - DoEncryptionOrEscrowRequest(net::HTTP_OK, "escrow_handle"); - - VerifyAndFinishRequest(net::HTTP_OK, - kAuthenticateInstrumentValidRequest, - kAuthenticateInstrumentFailureResponse); -} + delegate_.ExpectBaselineMetrics(); -TEST_F(WalletClientTest, AuthenticateInstrumentEscrowDown) { - EXPECT_CALL(delegate_, OnWalletError(WalletClient::NETWORK_ERROR)).Times(1); - delegate_.ExpectLogWalletApiCallDuration( - AutofillMetrics::AUTHENTICATE_INSTRUMENT, - 0); - delegate_.ExpectBaselineMetrics(HAS_ESCROW_REQUEST, NO_WALLET_REQUEST); - delegate_.ExpectWalletErrorMetric(AutofillMetrics::WALLET_NETWORK_ERROR); - - wallet_client_->AuthenticateInstrument("instrument_id", - "cvv", - "obfuscated_gaia_id"); + wallet_client_->AuthenticateInstrument("instrument_id", "123"); - DoEncryptionOrEscrowRequest(net::HTTP_INTERNAL_SERVER_ERROR, std::string()); -} - -TEST_F(WalletClientTest, AuthenticateInstrumentEscrowMalformed) { - EXPECT_CALL(delegate_, - OnWalletError(WalletClient::MALFORMED_RESPONSE)).Times(1); - delegate_.ExpectLogWalletApiCallDuration( - AutofillMetrics::AUTHENTICATE_INSTRUMENT, - 0); - delegate_.ExpectBaselineMetrics(HAS_ESCROW_REQUEST, NO_WALLET_REQUEST); - delegate_.ExpectWalletErrorMetric(AutofillMetrics::WALLET_MALFORMED_RESPONSE); - - wallet_client_->AuthenticateInstrument("instrument_id", - "cvv", - "obfuscated_gaia_id"); - - DoEncryptionOrEscrowRequest(net::HTTP_OK, std::string()); + VerifyAndFinishFormEncodedRequest(net::HTTP_OK, + kAuthenticateInstrumentValidRequest, + kAuthenticateInstrumentFailureResponse, + 3U); } TEST_F(WalletClientTest, AuthenticateInstrumentFailedMalformedResponse) { @@ -1094,18 +982,15 @@ TEST_F(WalletClientTest, AuthenticateInstrumentFailedMalformedResponse) { delegate_.ExpectLogWalletApiCallDuration( AutofillMetrics::AUTHENTICATE_INSTRUMENT, 1); - delegate_.ExpectBaselineMetrics(HAS_ESCROW_REQUEST, HAS_WALLET_REQUEST); + delegate_.ExpectBaselineMetrics(); delegate_.ExpectWalletErrorMetric(AutofillMetrics::WALLET_MALFORMED_RESPONSE); - wallet_client_->AuthenticateInstrument("instrument_id", - "cvv", - "obfuscated_gaia_id"); - - DoEncryptionOrEscrowRequest(net::HTTP_OK, "escrow_handle"); + wallet_client_->AuthenticateInstrument("instrument_id", "123"); - VerifyAndFinishRequest(net::HTTP_OK, - kAuthenticateInstrumentValidRequest, - kSaveInvalidResponse); + VerifyAndFinishFormEncodedRequest(net::HTTP_OK, + kAuthenticateInstrumentValidRequest, + kSaveInvalidResponse, + 3U); } // TODO(ahutter): Add failure tests for GetWalletItems. @@ -1113,7 +998,7 @@ TEST_F(WalletClientTest, AuthenticateInstrumentFailedMalformedResponse) { TEST_F(WalletClientTest, GetWalletItems) { delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::GET_WALLET_ITEMS, 1); - delegate_.ExpectBaselineMetrics(NO_ESCROW_REQUEST, HAS_WALLET_REQUEST); + delegate_.ExpectBaselineMetrics(); wallet_client_->GetWalletItems(GURL(kMerchantUrl)); @@ -1125,22 +1010,25 @@ TEST_F(WalletClientTest, GetWalletItems) { TEST_F(WalletClientTest, SaveAddressSucceeded) { EXPECT_CALL(delegate_, - OnDidSaveAddress("saved_address_id", - std::vector<RequiredAction>(), - std::vector<FormFieldError>())).Times(1); - delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::SAVE_ADDRESS, 1); - delegate_.ExpectBaselineMetrics(NO_ESCROW_REQUEST, HAS_WALLET_REQUEST); + OnDidSaveToWallet(std::string(), + "saved_address_id", + std::vector<RequiredAction>(), + std::vector<FormFieldError>())).Times(1); + delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::SAVE_TO_WALLET, 1); + delegate_.ExpectBaselineMetrics(); scoped_ptr<Address> address = GetTestSaveableAddress(); - wallet_client_->SaveAddress(*address, GURL(kMerchantUrl)); + wallet_client_->SaveToWallet(scoped_ptr<Instrument>(), + address.Pass(), + GURL(kMerchantUrl)); VerifyAndFinishRequest(net::HTTP_OK, kSaveAddressValidRequest, kSaveAddressValidResponse); } TEST_F(WalletClientTest, SaveAddressWithRequiredActionsSucceeded) { - delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::SAVE_ADDRESS, 1); - delegate_.ExpectBaselineMetrics(NO_ESCROW_REQUEST, HAS_WALLET_REQUEST); + delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::SAVE_TO_WALLET, 1); + delegate_.ExpectBaselineMetrics(); delegate_.ExpectWalletRequiredActionMetric( AutofillMetrics::REQUIRE_PHONE_NUMBER); delegate_.ExpectWalletRequiredActionMetric( @@ -1155,12 +1043,15 @@ TEST_F(WalletClientTest, SaveAddressWithRequiredActionsSucceeded) { FormFieldError::SHIPPING_ADDRESS)); EXPECT_CALL(delegate_, - OnDidSaveAddress(std::string(), - required_actions, - form_errors)).Times(1); + OnDidSaveToWallet(std::string(), + std::string(), + required_actions, + form_errors)).Times(1); scoped_ptr<Address> address = GetTestSaveableAddress(); - wallet_client_->SaveAddress(*address, GURL(kMerchantUrl)); + wallet_client_->SaveToWallet(scoped_ptr<Instrument>(), + address.Pass(), + GURL(kMerchantUrl)); VerifyAndFinishRequest(net::HTTP_OK, kSaveAddressValidRequest, kSaveAddressWithRequiredActionsValidResponse); @@ -1169,12 +1060,14 @@ TEST_F(WalletClientTest, SaveAddressWithRequiredActionsSucceeded) { TEST_F(WalletClientTest, SaveAddressFailedInvalidRequiredAction) { EXPECT_CALL(delegate_, OnWalletError(WalletClient::MALFORMED_RESPONSE)).Times(1); - delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::SAVE_ADDRESS, 1); - delegate_.ExpectBaselineMetrics(NO_ESCROW_REQUEST, HAS_WALLET_REQUEST); + delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::SAVE_TO_WALLET, 1); + delegate_.ExpectBaselineMetrics(); delegate_.ExpectWalletErrorMetric(AutofillMetrics::WALLET_MALFORMED_RESPONSE); scoped_ptr<Address> address = GetTestSaveableAddress(); - wallet_client_->SaveAddress(*address, GURL(kMerchantUrl)); + wallet_client_->SaveToWallet(scoped_ptr<Instrument>(), + address.Pass(), + GURL(kMerchantUrl)); VerifyAndFinishRequest(net::HTTP_OK, kSaveAddressValidRequest, kSaveWithInvalidRequiredActionsResponse); @@ -1183,12 +1076,14 @@ TEST_F(WalletClientTest, SaveAddressFailedInvalidRequiredAction) { TEST_F(WalletClientTest, SaveAddressFailedMalformedResponse) { EXPECT_CALL(delegate_, OnWalletError(WalletClient::MALFORMED_RESPONSE)).Times(1); - delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::SAVE_ADDRESS, 1); - delegate_.ExpectBaselineMetrics(NO_ESCROW_REQUEST, HAS_WALLET_REQUEST); + delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::SAVE_TO_WALLET, 1); + delegate_.ExpectBaselineMetrics(); delegate_.ExpectWalletErrorMetric(AutofillMetrics::WALLET_MALFORMED_RESPONSE); scoped_ptr<Address> address = GetTestSaveableAddress(); - wallet_client_->SaveAddress(*address, GURL(kMerchantUrl)); + wallet_client_->SaveToWallet(scoped_ptr<Instrument>(), + address.Pass(), + GURL(kMerchantUrl)); VerifyAndFinishRequest(net::HTTP_OK, kSaveAddressValidRequest, kSaveInvalidResponse); @@ -1196,27 +1091,27 @@ TEST_F(WalletClientTest, SaveAddressFailedMalformedResponse) { TEST_F(WalletClientTest, SaveInstrumentSucceeded) { EXPECT_CALL(delegate_, - OnDidSaveInstrument("instrument_id", - std::vector<RequiredAction>(), - std::vector<FormFieldError>())).Times(1); - delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::SAVE_INSTRUMENT, 1); - delegate_.ExpectBaselineMetrics(HAS_ESCROW_REQUEST, HAS_WALLET_REQUEST); + OnDidSaveToWallet("instrument_id", + std::string(), + std::vector<RequiredAction>(), + std::vector<FormFieldError>())).Times(1); + delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::SAVE_TO_WALLET, 1); + delegate_.ExpectBaselineMetrics(); scoped_ptr<Instrument> instrument = GetTestInstrument(); - wallet_client_->SaveInstrument(*instrument, - "obfuscated_gaia_id", - GURL(kMerchantUrl)); - - DoEncryptionOrEscrowRequest(net::HTTP_OK, "escrow_handle"); - - VerifyAndFinishRequest(net::HTTP_OK, - kSaveInstrumentValidRequest, - kSaveInstrumentValidResponse); + wallet_client_->SaveToWallet(instrument.Pass(), + scoped_ptr<Address>(), + GURL(kMerchantUrl)); + + VerifyAndFinishFormEncodedRequest(net::HTTP_OK, + kSaveInstrumentValidRequest, + kSaveInstrumentValidResponse, + 4U); } TEST_F(WalletClientTest, SaveInstrumentWithRequiredActionsSucceeded) { - delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::SAVE_INSTRUMENT, 1); - delegate_.ExpectBaselineMetrics(HAS_ESCROW_REQUEST, HAS_WALLET_REQUEST); + delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::SAVE_TO_WALLET, 1); + delegate_.ExpectBaselineMetrics(); delegate_.ExpectWalletRequiredActionMetric( AutofillMetrics::REQUIRE_PHONE_NUMBER); delegate_.ExpectWalletRequiredActionMetric( @@ -1231,120 +1126,88 @@ TEST_F(WalletClientTest, SaveInstrumentWithRequiredActionsSucceeded) { FormFieldError::SHIPPING_ADDRESS)); EXPECT_CALL(delegate_, - OnDidSaveInstrument(std::string(), - required_actions, - form_errors)).Times(1); + OnDidSaveToWallet(std::string(), + std::string(), + required_actions, + form_errors)).Times(1); scoped_ptr<Instrument> instrument = GetTestInstrument(); - wallet_client_->SaveInstrument(*instrument, - "obfuscated_gaia_id", - GURL(kMerchantUrl)); + wallet_client_->SaveToWallet(instrument.Pass(), + scoped_ptr<Address>(), + GURL(kMerchantUrl)); - DoEncryptionOrEscrowRequest(net::HTTP_OK, "escrow_handle"); - - VerifyAndFinishRequest(net::HTTP_OK, - kSaveInstrumentValidRequest, - kSaveInstrumentWithRequiredActionsValidResponse); + VerifyAndFinishFormEncodedRequest( + net::HTTP_OK, + kSaveInstrumentValidRequest, + kSaveInstrumentWithRequiredActionsValidResponse, + 4U); } TEST_F(WalletClientTest, SaveInstrumentFailedInvalidRequiredActions) { - delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::SAVE_INSTRUMENT, 1); - delegate_.ExpectBaselineMetrics(HAS_ESCROW_REQUEST, HAS_WALLET_REQUEST); + delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::SAVE_TO_WALLET, 1); + delegate_.ExpectBaselineMetrics(); delegate_.ExpectWalletErrorMetric(AutofillMetrics::WALLET_MALFORMED_RESPONSE); EXPECT_CALL(delegate_, OnWalletError(WalletClient::MALFORMED_RESPONSE)); scoped_ptr<Instrument> instrument = GetTestInstrument(); - wallet_client_->SaveInstrument(*instrument, - "obfuscated_gaia_id", - GURL(kMerchantUrl)); - - DoEncryptionOrEscrowRequest(net::HTTP_OK, "escrow_handle"); - - VerifyAndFinishRequest(net::HTTP_OK, - kSaveInstrumentValidRequest, - kSaveWithInvalidRequiredActionsResponse); -} - -TEST_F(WalletClientTest, SaveInstrumentEscrowDown) { - EXPECT_CALL(delegate_, OnWalletError(WalletClient::NETWORK_ERROR)).Times(1); - delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::SAVE_INSTRUMENT, 0); - delegate_.ExpectBaselineMetrics(HAS_ESCROW_REQUEST, NO_WALLET_REQUEST); - delegate_.ExpectWalletErrorMetric(AutofillMetrics::WALLET_NETWORK_ERROR); - - scoped_ptr<Instrument> instrument = GetTestInstrument(); - wallet_client_->SaveInstrument(*instrument, - "obfuscated_gaia_id", - GURL(kMerchantUrl)); - - DoEncryptionOrEscrowRequest(net::HTTP_INTERNAL_SERVER_ERROR, std::string()); -} - -TEST_F(WalletClientTest, SaveInstrumentEscrowMalformed) { - EXPECT_CALL(delegate_, - OnWalletError(WalletClient::MALFORMED_RESPONSE)).Times(1); - delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::SAVE_INSTRUMENT, 0); - delegate_.ExpectBaselineMetrics(HAS_ESCROW_REQUEST, NO_WALLET_REQUEST); - delegate_.ExpectWalletErrorMetric(AutofillMetrics::WALLET_MALFORMED_RESPONSE); - - scoped_ptr<Instrument> instrument = GetTestInstrument(); - wallet_client_->SaveInstrument(*instrument, - "obfuscated_gaia_id", - GURL(kMerchantUrl)); - - DoEncryptionOrEscrowRequest(net::HTTP_OK, std::string()); + wallet_client_->SaveToWallet(instrument.Pass(), + scoped_ptr<Address>(), + GURL(kMerchantUrl)); + + VerifyAndFinishFormEncodedRequest(net::HTTP_OK, + kSaveInstrumentValidRequest, + kSaveWithInvalidRequiredActionsResponse, + 4U); } TEST_F(WalletClientTest, SaveInstrumentFailedMalformedResponse) { EXPECT_CALL(delegate_, OnWalletError(WalletClient::MALFORMED_RESPONSE)).Times(1); - delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::SAVE_INSTRUMENT, 1); - delegate_.ExpectBaselineMetrics(HAS_ESCROW_REQUEST, HAS_WALLET_REQUEST); + delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::SAVE_TO_WALLET, 1); + delegate_.ExpectBaselineMetrics(); delegate_.ExpectWalletErrorMetric(AutofillMetrics::WALLET_MALFORMED_RESPONSE); scoped_ptr<Instrument> instrument = GetTestInstrument(); - wallet_client_->SaveInstrument(*instrument, - "obfuscated_gaia_id", - GURL(kMerchantUrl)); - - DoEncryptionOrEscrowRequest(net::HTTP_OK, "escrow_handle"); - - VerifyAndFinishRequest(net::HTTP_OK, - kSaveInstrumentValidRequest, - kSaveInvalidResponse); + wallet_client_->SaveToWallet(instrument.Pass(), + scoped_ptr<Address>(), + GURL(kMerchantUrl)); + + VerifyAndFinishFormEncodedRequest(net::HTTP_OK, + kSaveInstrumentValidRequest, + kSaveInvalidResponse, + 4U); } TEST_F(WalletClientTest, SaveInstrumentAndAddressSucceeded) { EXPECT_CALL(delegate_, - OnDidSaveInstrumentAndAddress( - "saved_instrument_id", - "saved_address_id", - std::vector<RequiredAction>(), - std::vector<FormFieldError>())).Times(1); + OnDidSaveToWallet("saved_instrument_id", + "saved_address_id", + std::vector<RequiredAction>(), + std::vector<FormFieldError>())).Times(1); delegate_.ExpectLogWalletApiCallDuration( - AutofillMetrics::SAVE_INSTRUMENT_AND_ADDRESS, + AutofillMetrics::SAVE_TO_WALLET, 1); - delegate_.ExpectBaselineMetrics(HAS_ESCROW_REQUEST, HAS_WALLET_REQUEST); + delegate_.ExpectBaselineMetrics(); scoped_ptr<Instrument> instrument = GetTestInstrument(); scoped_ptr<Address> address = GetTestSaveableAddress(); - wallet_client_->SaveInstrumentAndAddress(*instrument, - *address, - "obfuscated_gaia_id", - GURL(kMerchantUrl)); - - DoEncryptionOrEscrowRequest(net::HTTP_OK, "escrow_handle"); - VerifyAndFinishRequest(net::HTTP_OK, - kSaveInstrumentAndAddressValidRequest, - kSaveInstrumentAndAddressValidResponse); + wallet_client_->SaveToWallet(instrument.Pass(), + address.Pass(), + GURL(kMerchantUrl)); + + VerifyAndFinishFormEncodedRequest(net::HTTP_OK, + kSaveInstrumentAndAddressValidRequest, + kSaveInstrumentAndAddressValidResponse, + 4U); } TEST_F(WalletClientTest, SaveInstrumentAndAddressWithRequiredActionsSucceeded) { delegate_.ExpectLogWalletApiCallDuration( - AutofillMetrics::SAVE_INSTRUMENT_AND_ADDRESS, + AutofillMetrics::SAVE_TO_WALLET, 1); - delegate_.ExpectBaselineMetrics(HAS_ESCROW_REQUEST, HAS_WALLET_REQUEST); + delegate_.ExpectBaselineMetrics(); delegate_.ExpectWalletRequiredActionMetric( AutofillMetrics::REQUIRE_PHONE_NUMBER); delegate_.ExpectWalletRequiredActionMetric( @@ -1359,152 +1222,68 @@ TEST_F(WalletClientTest, SaveInstrumentAndAddressWithRequiredActionsSucceeded) { FormFieldError::SHIPPING_ADDRESS)); EXPECT_CALL(delegate_, - OnDidSaveInstrumentAndAddress( - std::string(), - std::string(), - required_actions, - form_errors)).Times(1); + OnDidSaveToWallet(std::string(), + std::string(), + required_actions, + form_errors)).Times(1); scoped_ptr<Instrument> instrument = GetTestInstrument(); scoped_ptr<Address> address = GetTestSaveableAddress(); - wallet_client_->SaveInstrumentAndAddress(*instrument, - *address, - "obfuscated_gaia_id", - GURL(kMerchantUrl)); + wallet_client_->SaveToWallet(instrument.Pass(), + address.Pass(), + GURL(kMerchantUrl)); - DoEncryptionOrEscrowRequest(net::HTTP_OK, "escrow_handle"); - VerifyAndFinishRequest( + VerifyAndFinishFormEncodedRequest( net::HTTP_OK, kSaveInstrumentAndAddressValidRequest, - kSaveInstrumentAndAddressWithRequiredActionsValidResponse); + kSaveInstrumentAndAddressWithRequiredActionsValidResponse, + 4U); } TEST_F(WalletClientTest, SaveInstrumentAndAddressFailedInvalidRequiredAction) { EXPECT_CALL(delegate_, OnWalletError(WalletClient::MALFORMED_RESPONSE)).Times(1); delegate_.ExpectLogWalletApiCallDuration( - AutofillMetrics::SAVE_INSTRUMENT_AND_ADDRESS, - 1); - delegate_.ExpectBaselineMetrics(HAS_ESCROW_REQUEST, HAS_WALLET_REQUEST); - delegate_.ExpectWalletErrorMetric(AutofillMetrics::WALLET_MALFORMED_RESPONSE); - - scoped_ptr<Instrument> instrument = GetTestInstrument(); - scoped_ptr<Address> address = GetTestSaveableAddress(); - wallet_client_->SaveInstrumentAndAddress(*instrument, - *address, - "obfuscated_gaia_id", - GURL(kMerchantUrl)); - - DoEncryptionOrEscrowRequest(net::HTTP_OK, "escrow_handle"); - - VerifyAndFinishRequest(net::HTTP_OK, - kSaveInstrumentAndAddressValidRequest, - kSaveWithInvalidRequiredActionsResponse); -} - -TEST_F(WalletClientTest, SaveInstrumentAndAddressEscrowDown) { - EXPECT_CALL(delegate_, OnWalletError(WalletClient::NETWORK_ERROR)).Times(1); - delegate_.ExpectLogWalletApiCallDuration( - AutofillMetrics::SAVE_INSTRUMENT_AND_ADDRESS, - 0); - delegate_.ExpectBaselineMetrics(HAS_ESCROW_REQUEST, NO_WALLET_REQUEST); - delegate_.ExpectWalletErrorMetric(AutofillMetrics::WALLET_NETWORK_ERROR); - - scoped_ptr<Instrument> instrument = GetTestInstrument(); - scoped_ptr<Address> address = GetTestSaveableAddress(); - wallet_client_->SaveInstrumentAndAddress(*instrument, - *address, - "obfuscated_gaia_id", - GURL(kMerchantUrl)); - - DoEncryptionOrEscrowRequest(net::HTTP_INTERNAL_SERVER_ERROR, std::string()); -} - -TEST_F(WalletClientTest, SaveInstrumentAndAddressEscrowMalformed) { - EXPECT_CALL(delegate_, - OnWalletError(WalletClient::MALFORMED_RESPONSE)).Times(1); - delegate_.ExpectLogWalletApiCallDuration( - AutofillMetrics::SAVE_INSTRUMENT_AND_ADDRESS, - 0); - delegate_.ExpectBaselineMetrics(HAS_ESCROW_REQUEST, NO_WALLET_REQUEST); - delegate_.ExpectWalletErrorMetric(AutofillMetrics::WALLET_MALFORMED_RESPONSE); - - scoped_ptr<Instrument> instrument = GetTestInstrument(); - scoped_ptr<Address> address = GetTestSaveableAddress(); - wallet_client_->SaveInstrumentAndAddress(*instrument, - *address, - "obfuscated_gaia_id", - GURL(kMerchantUrl)); - - DoEncryptionOrEscrowRequest(net::HTTP_OK, std::string()); -} - -TEST_F(WalletClientTest, SaveInstrumentAndAddressFailedAddressMissing) { - EXPECT_CALL(delegate_, - OnWalletError(WalletClient::MALFORMED_RESPONSE)).Times(1); - delegate_.ExpectLogWalletApiCallDuration( - AutofillMetrics::SAVE_INSTRUMENT_AND_ADDRESS, - 1); - delegate_.ExpectBaselineMetrics(HAS_ESCROW_REQUEST, HAS_WALLET_REQUEST); - delegate_.ExpectWalletErrorMetric(AutofillMetrics::WALLET_MALFORMED_RESPONSE); - - scoped_ptr<Instrument> instrument = GetTestInstrument(); - scoped_ptr<Address> address = GetTestSaveableAddress(); - wallet_client_->SaveInstrumentAndAddress(*instrument, - *address, - "obfuscated_gaia_id", - GURL(kMerchantUrl)); - - DoEncryptionOrEscrowRequest(net::HTTP_OK, "escrow_handle"); - - VerifyAndFinishRequest(net::HTTP_OK, - kSaveInstrumentAndAddressValidRequest, - kSaveInstrumentAndAddressMissingAddressResponse); -} - -TEST_F(WalletClientTest, SaveInstrumentAndAddressFailedInstrumentMissing) { - EXPECT_CALL(delegate_, - OnWalletError(WalletClient::MALFORMED_RESPONSE)).Times(1); - delegate_.ExpectLogWalletApiCallDuration( - AutofillMetrics::SAVE_INSTRUMENT_AND_ADDRESS, + AutofillMetrics::SAVE_TO_WALLET, 1); - delegate_.ExpectBaselineMetrics(HAS_ESCROW_REQUEST, HAS_WALLET_REQUEST); + delegate_.ExpectBaselineMetrics(); delegate_.ExpectWalletErrorMetric(AutofillMetrics::WALLET_MALFORMED_RESPONSE); scoped_ptr<Instrument> instrument = GetTestInstrument(); scoped_ptr<Address> address = GetTestSaveableAddress(); - wallet_client_->SaveInstrumentAndAddress(*instrument, - *address, - "obfuscated_gaia_id", - GURL(kMerchantUrl)); - - DoEncryptionOrEscrowRequest(net::HTTP_OK, "escrow_handle"); - - VerifyAndFinishRequest(net::HTTP_OK, - kSaveInstrumentAndAddressValidRequest, - kSaveInstrumentAndAddressMissingInstrumentResponse); + wallet_client_->SaveToWallet(instrument.Pass(), + address.Pass(), + GURL(kMerchantUrl)); + + VerifyAndFinishFormEncodedRequest(net::HTTP_OK, + kSaveInstrumentAndAddressValidRequest, + kSaveWithInvalidRequiredActionsResponse, + 4U); } TEST_F(WalletClientTest, UpdateAddressSucceeded) { EXPECT_CALL(delegate_, - OnDidUpdateAddress("shipping_address_id", - std::vector<RequiredAction>(), - std::vector<FormFieldError>())).Times(1); - delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::UPDATE_ADDRESS, 1); - delegate_.ExpectBaselineMetrics(NO_ESCROW_REQUEST, HAS_WALLET_REQUEST); + OnDidSaveToWallet(std::string(), + "shipping_address_id", + std::vector<RequiredAction>(), + std::vector<FormFieldError>())).Times(1); + delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::SAVE_TO_WALLET, 1); + delegate_.ExpectBaselineMetrics(); scoped_ptr<Address> address = GetTestShippingAddress(); address->set_object_id("shipping_address_id"); - wallet_client_->UpdateAddress(*address, GURL(kMerchantUrl)); + wallet_client_->SaveToWallet(scoped_ptr<Instrument>(), + address.Pass(), + GURL(kMerchantUrl)); VerifyAndFinishRequest(net::HTTP_OK, kUpdateAddressValidRequest, kUpdateAddressValidResponse); } TEST_F(WalletClientTest, UpdateAddressWithRequiredActionsSucceeded) { - delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::UPDATE_ADDRESS, 1); - delegate_.ExpectBaselineMetrics(NO_ESCROW_REQUEST, HAS_WALLET_REQUEST); + delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::SAVE_TO_WALLET, 1); + delegate_.ExpectBaselineMetrics(); delegate_.ExpectWalletRequiredActionMetric( AutofillMetrics::REQUIRE_PHONE_NUMBER); delegate_.ExpectWalletRequiredActionMetric( @@ -1518,14 +1297,17 @@ TEST_F(WalletClientTest, UpdateAddressWithRequiredActionsSucceeded) { form_errors.push_back(FormFieldError(FormFieldError::INVALID_POSTAL_CODE, FormFieldError::SHIPPING_ADDRESS)); - EXPECT_CALL(delegate_, OnDidUpdateAddress(std::string(), - required_actions, - form_errors)).Times(1); + EXPECT_CALL(delegate_, OnDidSaveToWallet(std::string(), + std::string(), + required_actions, + form_errors)).Times(1); scoped_ptr<Address> address = GetTestShippingAddress(); address->set_object_id("shipping_address_id"); - wallet_client_->UpdateAddress(*address, GURL(kMerchantUrl)); + wallet_client_->SaveToWallet(scoped_ptr<Instrument>(), + address.Pass(), + GURL(kMerchantUrl)); VerifyAndFinishRequest(net::HTTP_OK, kUpdateAddressValidRequest, kUpdateWithRequiredActionsValidResponse); @@ -1534,14 +1316,16 @@ TEST_F(WalletClientTest, UpdateAddressWithRequiredActionsSucceeded) { TEST_F(WalletClientTest, UpdateAddressFailedInvalidRequiredAction) { EXPECT_CALL(delegate_, OnWalletError(WalletClient::MALFORMED_RESPONSE)).Times(1); - delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::UPDATE_ADDRESS, 1); - delegate_.ExpectBaselineMetrics(NO_ESCROW_REQUEST, HAS_WALLET_REQUEST); + delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::SAVE_TO_WALLET, 1); + delegate_.ExpectBaselineMetrics(); delegate_.ExpectWalletErrorMetric(AutofillMetrics::WALLET_MALFORMED_RESPONSE); scoped_ptr<Address> address = GetTestShippingAddress(); address->set_object_id("shipping_address_id"); - wallet_client_->UpdateAddress(*address, GURL(kMerchantUrl)); + wallet_client_->SaveToWallet(scoped_ptr<Instrument>(), + address.Pass(), + GURL(kMerchantUrl)); VerifyAndFinishRequest(net::HTTP_OK, kUpdateAddressValidRequest, kSaveWithInvalidRequiredActionsResponse); @@ -1550,14 +1334,16 @@ TEST_F(WalletClientTest, UpdateAddressFailedInvalidRequiredAction) { TEST_F(WalletClientTest, UpdateAddressMalformedResponse) { EXPECT_CALL(delegate_, OnWalletError(WalletClient::MALFORMED_RESPONSE)).Times(1); - delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::UPDATE_ADDRESS, 1); - delegate_.ExpectBaselineMetrics(NO_ESCROW_REQUEST, HAS_WALLET_REQUEST); + delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::SAVE_TO_WALLET, 1); + delegate_.ExpectBaselineMetrics(); delegate_.ExpectWalletErrorMetric(AutofillMetrics::WALLET_MALFORMED_RESPONSE); scoped_ptr<Address> address = GetTestShippingAddress(); address->set_object_id("shipping_address_id"); - wallet_client_->UpdateAddress(*address, GURL(kMerchantUrl)); + wallet_client_->SaveToWallet(scoped_ptr<Instrument>(), + address.Pass(), + GURL(kMerchantUrl)); VerifyAndFinishRequest(net::HTTP_OK, kUpdateAddressValidRequest, kUpdateMalformedResponse); @@ -1565,18 +1351,17 @@ TEST_F(WalletClientTest, UpdateAddressMalformedResponse) { TEST_F(WalletClientTest, UpdateInstrumentAddressSucceeded) { EXPECT_CALL(delegate_, - OnDidUpdateInstrument("instrument_id", - std::vector<RequiredAction>(), - std::vector<FormFieldError>())).Times(1); - delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::UPDATE_INSTRUMENT, + OnDidSaveToWallet("instrument_id", + std::string(), + std::vector<RequiredAction>(), + std::vector<FormFieldError>())).Times(1); + delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::SAVE_TO_WALLET, 1); - delegate_.ExpectBaselineMetrics(NO_ESCROW_REQUEST, HAS_WALLET_REQUEST); + delegate_.ExpectBaselineMetrics(); - WalletClient::UpdateInstrumentRequest update_instrument_request( - "instrument_id", - GURL(kMerchantUrl)); - - wallet_client_->UpdateInstrument(update_instrument_request, GetTestAddress()); + wallet_client_->SaveToWallet(GetTestAddressUpgradeInstrument(), + scoped_ptr<Address>(), + GURL(kMerchantUrl)); VerifyAndFinishRequest(net::HTTP_OK, kUpdateInstrumentAddressValidRequest, @@ -1585,86 +1370,49 @@ TEST_F(WalletClientTest, UpdateInstrumentAddressSucceeded) { TEST_F(WalletClientTest, UpdateInstrumentExpirationDateSuceeded) { EXPECT_CALL(delegate_, - OnDidUpdateInstrument("instrument_id", - std::vector<RequiredAction>(), - std::vector<FormFieldError>())).Times(1); - delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::UPDATE_INSTRUMENT, + OnDidSaveToWallet("instrument_id", + std::string(), + std::vector<RequiredAction>(), + std::vector<FormFieldError>())).Times(1); + delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::SAVE_TO_WALLET, 1); - delegate_.ExpectBaselineMetrics(HAS_ESCROW_REQUEST, HAS_WALLET_REQUEST); - - WalletClient::UpdateInstrumentRequest update_instrument_request( - "instrument_id", - GURL(kMerchantUrl)); - update_instrument_request.expiration_month = 12; - update_instrument_request.expiration_year = 2015; - update_instrument_request.card_verification_number = - "card_verification_number"; - update_instrument_request.obfuscated_gaia_id = "obfuscated_gaia_id"; - wallet_client_->UpdateInstrument(update_instrument_request, - scoped_ptr<Address>()); + delegate_.ExpectBaselineMetrics(); - DoEncryptionOrEscrowRequest(net::HTTP_OK, "escrow_handle"); + wallet_client_->SaveToWallet(GetTestExpirationDateChangeInstrument(), + scoped_ptr<Address>(), + GURL(kMerchantUrl)); - VerifyAndFinishRequest(net::HTTP_OK, - kUpdateInstrumentExpirationDateValidRequest, - kUpdateInstrumentValidResponse); + VerifyAndFinishFormEncodedRequest(net::HTTP_OK, + kUpdateInstrumentExpirationDateValidRequest, + kUpdateInstrumentValidResponse, + 3U); } TEST_F(WalletClientTest, UpdateInstrumentAddressWithNameChangeSucceeded) { EXPECT_CALL(delegate_, - OnDidUpdateInstrument("instrument_id", - std::vector<RequiredAction>(), - std::vector<FormFieldError>())).Times(1); - delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::UPDATE_INSTRUMENT, + OnDidSaveToWallet("instrument_id", + std::string(), + std::vector<RequiredAction>(), + std::vector<FormFieldError>())).Times(1); + delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::SAVE_TO_WALLET, 1); - delegate_.ExpectBaselineMetrics(HAS_ESCROW_REQUEST, HAS_WALLET_REQUEST); - - WalletClient::UpdateInstrumentRequest update_instrument_request( - "instrument_id", - GURL(kMerchantUrl)); - update_instrument_request.card_verification_number = - "card_verification_number"; - update_instrument_request.obfuscated_gaia_id = "obfuscated_gaia_id"; - - wallet_client_->UpdateInstrument(update_instrument_request, GetTestAddress()); + delegate_.ExpectBaselineMetrics(); - DoEncryptionOrEscrowRequest(net::HTTP_OK, "escrow_handle"); - - VerifyAndFinishRequest(net::HTTP_OK, - kUpdateInstrumentAddressWithNameChangeValidRequest, - kUpdateInstrumentValidResponse); -} + wallet_client_->SaveToWallet(GetTestAddressNameChangeInstrument(), + scoped_ptr<Address>(), + GURL(kMerchantUrl)); -TEST_F(WalletClientTest, UpdateInstrumentAddressAndExpirationDateSucceeded) { - EXPECT_CALL(delegate_, - OnDidUpdateInstrument("instrument_id", - std::vector<RequiredAction>(), - std::vector<FormFieldError>())).Times(1); - delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::UPDATE_INSTRUMENT, - 1); - delegate_.ExpectBaselineMetrics(HAS_ESCROW_REQUEST, HAS_WALLET_REQUEST); - - WalletClient::UpdateInstrumentRequest update_instrument_request( - "instrument_id", - GURL(kMerchantUrl)); - update_instrument_request.expiration_month = 12; - update_instrument_request.expiration_year = 2015; - update_instrument_request.card_verification_number = - "card_verification_number"; - update_instrument_request.obfuscated_gaia_id = "obfuscated_gaia_id"; - wallet_client_->UpdateInstrument(update_instrument_request, GetTestAddress()); - - DoEncryptionOrEscrowRequest(net::HTTP_OK, "escrow_handle"); - - VerifyAndFinishRequest(net::HTTP_OK, - kUpdateInstrumentAddressAndExpirationDateValidRequest, - kUpdateInstrumentValidResponse); + VerifyAndFinishFormEncodedRequest( + net::HTTP_OK, + kUpdateInstrumentAddressWithNameChangeValidRequest, + kUpdateInstrumentValidResponse, + 3U); } TEST_F(WalletClientTest, UpdateInstrumentWithRequiredActionsSucceeded) { - delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::UPDATE_INSTRUMENT, + delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::SAVE_TO_WALLET, 1); - delegate_.ExpectBaselineMetrics(NO_ESCROW_REQUEST, HAS_WALLET_REQUEST); + delegate_.ExpectBaselineMetrics(); delegate_.ExpectWalletRequiredActionMetric( AutofillMetrics::REQUIRE_PHONE_NUMBER); delegate_.ExpectWalletRequiredActionMetric( @@ -1679,15 +1427,14 @@ TEST_F(WalletClientTest, UpdateInstrumentWithRequiredActionsSucceeded) { FormFieldError::SHIPPING_ADDRESS)); EXPECT_CALL(delegate_, - OnDidUpdateInstrument(std::string(), - required_actions, - form_errors)).Times(1); - - WalletClient::UpdateInstrumentRequest update_instrument_request( - "instrument_id", - GURL(kMerchantUrl)); + OnDidSaveToWallet(std::string(), + std::string(), + required_actions, + form_errors)).Times(1); - wallet_client_->UpdateInstrument(update_instrument_request, GetTestAddress()); + wallet_client_->SaveToWallet(GetTestAddressUpgradeInstrument(), + scoped_ptr<Address>(), + GURL(kMerchantUrl)); VerifyAndFinishRequest(net::HTTP_OK, kUpdateInstrumentAddressValidRequest, @@ -1697,54 +1444,31 @@ TEST_F(WalletClientTest, UpdateInstrumentWithRequiredActionsSucceeded) { TEST_F(WalletClientTest, UpdateInstrumentFailedInvalidRequiredAction) { EXPECT_CALL(delegate_, OnWalletError(WalletClient::MALFORMED_RESPONSE)).Times(1); - delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::UPDATE_INSTRUMENT, + delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::SAVE_TO_WALLET, 1); - delegate_.ExpectBaselineMetrics(NO_ESCROW_REQUEST, HAS_WALLET_REQUEST); + delegate_.ExpectBaselineMetrics(); delegate_.ExpectWalletErrorMetric(AutofillMetrics::WALLET_MALFORMED_RESPONSE); - WalletClient::UpdateInstrumentRequest update_instrument_request( - "instrument_id", - GURL(kMerchantUrl)); - - wallet_client_->UpdateInstrument(update_instrument_request, GetTestAddress()); + wallet_client_->SaveToWallet(GetTestAddressUpgradeInstrument(), + scoped_ptr<Address>(), + GURL(kMerchantUrl)); VerifyAndFinishRequest(net::HTTP_OK, kUpdateInstrumentAddressValidRequest, kSaveWithInvalidRequiredActionsResponse); } -TEST_F(WalletClientTest, UpdateInstrumentEscrowFailed) { - EXPECT_CALL(delegate_, OnWalletError(WalletClient::NETWORK_ERROR)).Times(1); - delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::UPDATE_INSTRUMENT, - 0); - delegate_.ExpectBaselineMetrics(HAS_ESCROW_REQUEST, NO_WALLET_REQUEST); - delegate_.ExpectWalletErrorMetric(AutofillMetrics::WALLET_NETWORK_ERROR); - - WalletClient::UpdateInstrumentRequest update_instrument_request( - "instrument_id", - GURL(kMerchantUrl)); - update_instrument_request.card_verification_number = - "card_verification_number"; - update_instrument_request.obfuscated_gaia_id = "obfuscated_gaia_id"; - - wallet_client_->UpdateInstrument(update_instrument_request, GetTestAddress()); - - DoEncryptionOrEscrowRequest(net::HTTP_INTERNAL_SERVER_ERROR, std::string()); -} - TEST_F(WalletClientTest, UpdateInstrumentMalformedResponse) { EXPECT_CALL(delegate_, OnWalletError(WalletClient::MALFORMED_RESPONSE)).Times(1); - delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::UPDATE_INSTRUMENT, + delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::SAVE_TO_WALLET, 1); - delegate_.ExpectBaselineMetrics(NO_ESCROW_REQUEST, HAS_WALLET_REQUEST); + delegate_.ExpectBaselineMetrics(); delegate_.ExpectWalletErrorMetric(AutofillMetrics::WALLET_MALFORMED_RESPONSE); - WalletClient::UpdateInstrumentRequest update_instrument_request( - "instrument_id", - GURL(kMerchantUrl)); - - wallet_client_->UpdateInstrument(update_instrument_request, GetTestAddress()); + wallet_client_->SaveToWallet(GetTestAddressUpgradeInstrument(), + scoped_ptr<Address>(), + GURL(kMerchantUrl)); VerifyAndFinishRequest(net::HTTP_OK, kUpdateInstrumentAddressValidRequest, @@ -1753,7 +1477,7 @@ TEST_F(WalletClientTest, UpdateInstrumentMalformedResponse) { TEST_F(WalletClientTest, SendAutocheckoutOfStatusSuccess) { delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::SEND_STATUS, 1); - delegate_.ExpectBaselineMetrics(NO_ESCROW_REQUEST, HAS_WALLET_REQUEST); + delegate_.ExpectBaselineMetrics(); AutocheckoutStatistic statistic; statistic.page_number = 1; @@ -1772,7 +1496,7 @@ TEST_F(WalletClientTest, SendAutocheckoutOfStatusSuccess) { TEST_F(WalletClientTest, SendAutocheckoutStatusOfFailure) { delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::SEND_STATUS, 1); - delegate_.ExpectBaselineMetrics(NO_ESCROW_REQUEST, HAS_WALLET_REQUEST); + delegate_.ExpectBaselineMetrics(); std::vector<AutocheckoutStatistic> statistics; wallet_client_->SendAutocheckoutStatus(autofill::CANNOT_PROCEED, @@ -1788,7 +1512,7 @@ TEST_F(WalletClientTest, HasRequestInProgress) { EXPECT_FALSE(wallet_client_->HasRequestInProgress()); delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::GET_WALLET_ITEMS, 1); - delegate_.ExpectBaselineMetrics(NO_ESCROW_REQUEST, HAS_WALLET_REQUEST); + delegate_.ExpectBaselineMetrics(); wallet_client_->GetWalletItems(GURL(kMerchantUrl)); EXPECT_TRUE(wallet_client_->HasRequestInProgress()); @@ -1803,7 +1527,7 @@ TEST_F(WalletClientTest, PendingRequest) { EXPECT_EQ(0U, wallet_client_->pending_requests_.size()); // Shouldn't queue the first request. - delegate_.ExpectBaselineMetrics(NO_ESCROW_REQUEST, HAS_WALLET_REQUEST); + delegate_.ExpectBaselineMetrics(); wallet_client_->GetWalletItems(GURL(kMerchantUrl)); EXPECT_EQ(0U, wallet_client_->pending_requests_.size()); testing::Mock::VerifyAndClear(delegate_.metric_logger()); @@ -1813,7 +1537,7 @@ TEST_F(WalletClientTest, PendingRequest) { delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::GET_WALLET_ITEMS, 1); - delegate_.ExpectBaselineMetrics(NO_ESCROW_REQUEST, HAS_WALLET_REQUEST); + delegate_.ExpectBaselineMetrics(); VerifyAndFinishRequest(net::HTTP_OK, kGetWalletItemsValidRequest, kGetWalletItemsValidResponse); @@ -1837,7 +1561,7 @@ TEST_F(WalletClientTest, CancelRequests) { ASSERT_EQ(0U, wallet_client_->pending_requests_.size()); delegate_.ExpectLogWalletApiCallDuration(AutofillMetrics::GET_WALLET_ITEMS, 0); - delegate_.ExpectBaselineMetrics(NO_ESCROW_REQUEST, HAS_WALLET_REQUEST); + delegate_.ExpectBaselineMetrics(); wallet_client_->GetWalletItems(GURL(kMerchantUrl)); wallet_client_->GetWalletItems(GURL(kMerchantUrl)); diff --git a/components/autofill/content/browser/wallet/wallet_service_url.cc b/components/autofill/content/browser/wallet/wallet_service_url.cc index a0c4e08..bebdf7f 100644 --- a/components/autofill/content/browser/wallet/wallet_service_url.cc +++ b/components/autofill/content/browser/wallet/wallet_service_url.cc @@ -63,6 +63,15 @@ GURL GetBaseSecureUrl() { return GURL(kSandboxWalletSecureServiceUrl); } +GURL GetBaseEncryptedFrontendUrl() { + const CommandLine& command_line = *CommandLine::ForCurrentProcess(); + // TODO(ahutter): Stop checking these switches once we switch over to prod. + GURL base_url = IsWalletProductionEnabled() || + command_line.HasSwitch(switches::kWalletServiceUrl) ? + GetWalletHostUrl() : GetBaseSecureUrl(); + return base_url.Resolve("online-secure/v2/autocheckout/v1/"); +} + } // namespace namespace wallet { @@ -72,7 +81,7 @@ GURL GetGetWalletItemsUrl() { } GURL GetGetFullWalletUrl() { - return GetBaseAutocheckoutUrl().Resolve("getFullWalletJwtless"); + return GetBaseEncryptedFrontendUrl().Resolve("getFullWalletJwtless?s7e=otp"); } GURL GetManageInstrumentsUrl() { @@ -88,43 +97,25 @@ GURL GetAcceptLegalDocumentsUrl() { } GURL GetAuthenticateInstrumentUrl() { - return GetBaseAutocheckoutUrl().Resolve("authenticateInstrument"); + return GetBaseEncryptedFrontendUrl() + .Resolve("authenticateInstrument?s7e=cvn"); } GURL GetSendStatusUrl() { return GetBaseAutocheckoutUrl().Resolve("reportStatus"); } -GURL GetSaveToWalletUrl() { +GURL GetSaveToWalletNoEscrowUrl() { return GetBaseAutocheckoutUrl().Resolve("saveToWallet"); } -GURL GetPassiveAuthUrl() { - return GetBaseWalletUrl().Resolve("passiveauth?isChromePayments=true"); -} - -GURL GetEncryptionUrl() { - const CommandLine& command_line = *CommandLine::ForCurrentProcess(); - // TODO(ahutter): Stop checking these switches once we switch over to prod. - if (IsWalletProductionEnabled() || - command_line.HasSwitch(switches::kWalletServiceUrl)) { - return GetWalletHostUrl().Resolve( - "online-secure/temporarydata/cvv?s7e=cvv"); - } else { - return GetBaseSecureUrl().Resolve( - "online-secure/temporarydata/cvv?s7e=cvv"); - } +GURL GetSaveToWalletUrl() { + return GetBaseEncryptedFrontendUrl() + .Resolve("saveToWallet?s7e=card_number%3Bcvn"); } -GURL GetEscrowUrl() { - const CommandLine& command_line = *CommandLine::ForCurrentProcess(); - // TODO(ahutter): Stop checking these switches once we switch over to prod. - if (IsWalletProductionEnabled() || - command_line.HasSwitch(switches::kWalletServiceUrl)) { - return GetBaseSecureUrl().Resolve("dehEfe?s7e=cardNumber%3Bcvv"); - } else { - return GetBaseSecureUrl().Resolve("checkout/dehEfe?s7e=cardNumber%3Bcvv"); - } +GURL GetPassiveAuthUrl() { + return GetBaseWalletUrl().Resolve("passiveauth?isChromePayments=true"); } GURL GetSignInUrl() { diff --git a/components/autofill/content/browser/wallet/wallet_service_url.h b/components/autofill/content/browser/wallet/wallet_service_url.h index a9a32fb..61bceca 100644 --- a/components/autofill/content/browser/wallet/wallet_service_url.h +++ b/components/autofill/content/browser/wallet/wallet_service_url.h @@ -16,9 +16,8 @@ GURL GetManageInstrumentsUrl(); GURL GetManageAddressesUrl(); GURL GetAcceptLegalDocumentsUrl(); GURL GetAuthenticateInstrumentUrl(); -GURL GetEncryptionUrl(); -GURL GetEscrowUrl(); GURL GetSendStatusUrl(); +GURL GetSaveToWalletNoEscrowUrl(); GURL GetSaveToWalletUrl(); GURL GetPassiveAuthUrl(); diff --git a/components/autofill/content/browser/wallet/wallet_service_url_unittest.cc b/components/autofill/content/browser/wallet/wallet_service_url_unittest.cc index be56057..793c95b 100644 --- a/components/autofill/content/browser/wallet/wallet_service_url_unittest.cc +++ b/components/autofill/content/browser/wallet/wallet_service_url_unittest.cc @@ -15,8 +15,8 @@ TEST(WalletServiceUrl, CheckDefaultUrls) { EXPECT_EQ("https://payments-form-dogfood.sandbox.google.com/online/v2/wallet/" "autocheckout/v1/getWalletItemsJwtless", GetGetWalletItemsUrl().spec()); - EXPECT_EQ("https://payments-form-dogfood.sandbox.google.com/online/v2/wallet/" - "autocheckout/v1/getFullWalletJwtless", + EXPECT_EQ("https://wallet-web.sandbox.google.com/online-secure/v2/" + "autocheckout/v1/getFullWalletJwtless?s7e=otp", GetGetFullWalletUrl().spec()); EXPECT_EQ("https://wallet-web.sandbox.google.com/manage/w/0/#paymentMethods:", GetManageInstrumentsUrl().spec()); @@ -26,24 +26,21 @@ TEST(WalletServiceUrl, CheckDefaultUrls) { EXPECT_EQ("https://payments-form-dogfood.sandbox.google.com/online/v2/wallet/" "autocheckout/v1/acceptLegalDocument", GetAcceptLegalDocumentsUrl().spec()); - EXPECT_EQ("https://payments-form-dogfood.sandbox.google.com/online/v2/wallet/" - "autocheckout/v1/authenticateInstrument", + EXPECT_EQ("https://wallet-web.sandbox.google.com/online-secure/v2/" + "autocheckout/v1/authenticateInstrument?s7e=cvn", GetAuthenticateInstrumentUrl().spec()); EXPECT_EQ("https://payments-form-dogfood.sandbox.google.com/online/v2/wallet/" "autocheckout/v1/reportStatus", GetSendStatusUrl().spec()); EXPECT_EQ("https://payments-form-dogfood.sandbox.google.com/online/v2/wallet/" "autocheckout/v1/saveToWallet", + GetSaveToWalletNoEscrowUrl().spec()); + EXPECT_EQ("https://wallet-web.sandbox.google.com/online-secure/v2/" + "autocheckout/v1/saveToWallet?s7e=card_number%3Bcvn", GetSaveToWalletUrl().spec()); EXPECT_EQ("https://payments-form-dogfood.sandbox.google.com/online/v2/" "passiveauth?isChromePayments=true", GetPassiveAuthUrl().spec()); - EXPECT_EQ("https://wallet-web.sandbox.google.com/online-secure/" - "temporarydata/cvv?s7e=cvv", - GetEncryptionUrl().spec()); - EXPECT_EQ("https://wallet-web.sandbox.google.com/checkout/dehEfe?" - "s7e=cardNumber%3Bcvv", - GetEscrowUrl().spec()); } TEST(WalletServiceUrl, IsUsingProd) { diff --git a/components/autofill/content/browser/wallet/wallet_test_util.cc b/components/autofill/content/browser/wallet/wallet_test_util.cc index ddc9e0e..de2538a 100644 --- a/components/autofill/content/browser/wallet/wallet_test_util.cc +++ b/components/autofill/content/browser/wallet/wallet_test_util.cc @@ -105,6 +105,39 @@ scoped_ptr<Instrument> GetTestInstrument() { GetTestAddress())); } +scoped_ptr<Instrument> GetTestAddressUpgradeInstrument() { + scoped_ptr<Instrument> instrument(new Instrument(base::string16(), + base::string16(), + 0, + 0, + Instrument::UNKNOWN, + GetTestAddress())); + instrument->set_object_id("instrument_id"); + return instrument.Pass(); +} + +scoped_ptr<Instrument> GetTestExpirationDateChangeInstrument() { + scoped_ptr<Instrument> instrument(new Instrument(base::string16(), + ASCIIToUTF16("123"), + 12, + FutureYear(), + Instrument::UNKNOWN, + scoped_ptr<Address>())); + instrument->set_object_id("instrument_id"); + return instrument.Pass(); +} + +scoped_ptr<Instrument> GetTestAddressNameChangeInstrument() { + scoped_ptr<Instrument> instrument(new Instrument(base::string16(), + ASCIIToUTF16("123"), + 0, + 0, + Instrument::UNKNOWN, + GetTestAddress())); + instrument->set_object_id("instrument_id"); + return instrument.Pass(); +} + scoped_ptr<WalletItems::LegalDocument> GetTestLegalDocument() { base::DictionaryValue dict; dict.SetString("legal_document_id", "document_id"); diff --git a/components/autofill/content/browser/wallet/wallet_test_util.h b/components/autofill/content/browser/wallet/wallet_test_util.h index e4978a6..813a1da 100644 --- a/components/autofill/content/browser/wallet/wallet_test_util.h +++ b/components/autofill/content/browser/wallet/wallet_test_util.h @@ -19,6 +19,9 @@ scoped_ptr<Address> GetTestAddress(); scoped_ptr<Address> GetTestMinimalAddress(); scoped_ptr<FullWallet> GetTestFullWallet(); scoped_ptr<Instrument> GetTestInstrument(); +scoped_ptr<Instrument> GetTestAddressUpgradeInstrument(); +scoped_ptr<Instrument> GetTestExpirationDateChangeInstrument(); +scoped_ptr<Instrument> GetTestAddressNameChangeInstrument(); scoped_ptr<WalletItems::LegalDocument> GetTestLegalDocument(); scoped_ptr<WalletItems::MaskedInstrument> GetTestMaskedInstrument(); scoped_ptr<WalletItems::MaskedInstrument> GetTestMaskedInstrumentExpired(); |