Index: components/autofill/core/browser/autofill_manager_unittest.cc |
diff --git a/components/autofill/core/browser/autofill_manager_unittest.cc b/components/autofill/core/browser/autofill_manager_unittest.cc |
index e9d94a48d4007bdfa171308b4ec47b95e6fa3aa5..0baf323fc291a3db027f825ebbbb31e9b51ae726 100644 |
--- a/components/autofill/core/browser/autofill_manager_unittest.cc |
+++ b/components/autofill/core/browser/autofill_manager_unittest.cc |
@@ -121,9 +121,11 @@ class TestPaymentsClient : public payments::PaymentsClient { |
void UploadCard(const payments::PaymentsClient::UploadRequestDetails& |
request_details) override { |
- delegate_->OnDidUploadCard(AutofillClient::SUCCESS); |
+ delegate_->OnDidUploadCard(AutofillClient::SUCCESS, server_id_); |
} |
+ std::string server_id_; |
+ |
private: |
payments::PaymentsClientDelegate* const delegate_; |
@@ -180,6 +182,13 @@ class TestPersonalDataManager : public PersonalDataManager { |
local_credit_cards_.push_back(std::move(local_credit_card)); |
} |
+ void AddServerCreditCard(const CreditCard& credit_card) override { |
+ std::unique_ptr<CreditCard> server_credit_card = |
+ base::MakeUnique<CreditCard>(credit_card); |
+ server_credit_card->set_modification_date(base::Time::Now()); |
+ server_credit_cards_.push_back(std::move(server_credit_card)); |
+ } |
+ |
void RecordUseOf(const AutofillDataModel& data_model) override { |
CreditCard* credit_card = GetCreditCardWithGUID(data_model.guid().c_str()); |
if (credit_card) |
@@ -216,6 +225,7 @@ class TestPersonalDataManager : public PersonalDataManager { |
void ClearCreditCards() { |
local_credit_cards_.clear(); |
+ server_credit_cards_.clear(); |
} |
// Create Elvis card with whitespace in the credit card number. |
@@ -528,6 +538,136 @@ class MockAutofillDriver : public TestAutofillDriver { |
DISALLOW_COPY_AND_ASSIGN(MockAutofillDriver); |
}; |
+class TestAutofillExternalDelegate : public AutofillExternalDelegate { |
+ public: |
+ explicit TestAutofillExternalDelegate(AutofillManager* autofill_manager, |
+ AutofillDriver* autofill_driver) |
+ : AutofillExternalDelegate(autofill_manager, autofill_driver), |
+ on_query_seen_(false), |
+ on_suggestions_returned_seen_(false) {} |
+ ~TestAutofillExternalDelegate() override {} |
+ |
+ void OnQuery(int query_id, |
+ const FormData& form, |
+ const FormFieldData& field, |
+ const gfx::RectF& bounds) override { |
+ on_query_seen_ = true; |
+ on_suggestions_returned_seen_ = false; |
+ } |
+ |
+ void OnSuggestionsReturned( |
+ int query_id, |
+ const std::vector<Suggestion>& suggestions) override { |
+ on_suggestions_returned_seen_ = true; |
+ query_id_ = query_id; |
+ suggestions_ = suggestions; |
+ } |
+ |
+ void CheckSuggestions(int expected_page_id, |
+ size_t expected_num_suggestions, |
+ const Suggestion expected_suggestions[]) { |
+ // Ensure that these results are from the most recent query. |
+ EXPECT_TRUE(on_suggestions_returned_seen_); |
+ |
+ EXPECT_EQ(expected_page_id, query_id_); |
+ ASSERT_LE(expected_num_suggestions, suggestions_.size()); |
+ for (size_t i = 0; i < expected_num_suggestions; ++i) { |
+ SCOPED_TRACE(base::StringPrintf("i: %" PRIuS, i)); |
+ EXPECT_EQ(expected_suggestions[i].value, suggestions_[i].value); |
+ EXPECT_EQ(expected_suggestions[i].label, suggestions_[i].label); |
+ EXPECT_EQ(expected_suggestions[i].icon, suggestions_[i].icon); |
+ EXPECT_EQ(expected_suggestions[i].frontend_id, |
+ suggestions_[i].frontend_id); |
+ } |
+ ASSERT_EQ(expected_num_suggestions, suggestions_.size()); |
+ } |
+ |
+ // Wrappers around the above GetSuggestions call that take a hardcoded number |
+ // of expected results so callsites are cleaner. |
+ void CheckSuggestions(int expected_page_id, const Suggestion& suggestion0) { |
+ std::vector<Suggestion> suggestion_vector; |
+ suggestion_vector.push_back(suggestion0); |
+ CheckSuggestions(expected_page_id, 1, &suggestion_vector[0]); |
+ } |
+ void CheckSuggestions(int expected_page_id, |
+ const Suggestion& suggestion0, |
+ const Suggestion& suggestion1) { |
+ std::vector<Suggestion> suggestion_vector; |
+ suggestion_vector.push_back(suggestion0); |
+ suggestion_vector.push_back(suggestion1); |
+ CheckSuggestions(expected_page_id, 2, &suggestion_vector[0]); |
+ } |
+ void CheckSuggestions(int expected_page_id, |
+ const Suggestion& suggestion0, |
+ const Suggestion& suggestion1, |
+ const Suggestion& suggestion2) { |
+ std::vector<Suggestion> suggestion_vector; |
+ suggestion_vector.push_back(suggestion0); |
+ suggestion_vector.push_back(suggestion1); |
+ suggestion_vector.push_back(suggestion2); |
+ CheckSuggestions(expected_page_id, 3, &suggestion_vector[0]); |
+ } |
+ // Check that the autofill suggestions were sent, and that they match a page |
+ // but contain no results. |
+ void CheckNoSuggestions(int expected_page_id) { |
+ CheckSuggestions(expected_page_id, 0, nullptr); |
+ } |
+ // Check that the autofill suggestions were sent, and that they match a page |
+ // and contain a specific number of suggestions. |
+ void CheckSuggestionCount(int expected_page_id, |
+ size_t expected_num_suggestions) { |
+ // Ensure that these results are from the most recent query. |
+ EXPECT_TRUE(on_suggestions_returned_seen_); |
+ |
+ EXPECT_EQ(expected_page_id, query_id_); |
+ ASSERT_EQ(expected_num_suggestions, suggestions_.size()); |
+ } |
+ |
+ bool on_query_seen() const { return on_query_seen_; } |
+ |
+ bool on_suggestions_returned_seen() const { |
+ return on_suggestions_returned_seen_; |
+ } |
+ |
+ private: |
+ // Records if OnQuery has been called yet. |
+ bool on_query_seen_; |
+ |
+ // Records if OnSuggestionsReturned has been called after the most recent |
+ // call to OnQuery. |
+ bool on_suggestions_returned_seen_; |
+ |
+ // The query id of the most recent Autofill query. |
+ int query_id_; |
+ |
+ // The results returned by the most recent Autofill query. |
+ std::vector<Suggestion> suggestions_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(TestAutofillExternalDelegate); |
+}; |
+ |
+// Finds the specified UKM metric by |name| in the specified UKM |metrics|. |
+const ukm::Entry_Metric* FindMetric( |
+ const char* name, |
+ const google::protobuf::RepeatedPtrField<ukm::Entry_Metric>& metrics) { |
+ for (const auto& metric : metrics) { |
+ if (metric.metric_hash() == base::HashMetricName(name)) |
+ return &metric; |
+ } |
+ return nullptr; |
+} |
+ |
+// Get Ukm sources from the Ukm service. |
+std::vector<const ukm::UkmSource*> GetUkmSources(ukm::TestUkmService* service) { |
+ std::vector<const ukm::UkmSource*> sources; |
+ for (const auto& kv : service->GetSources()) |
+ sources.push_back(kv.second.get()); |
+ |
+ return sources; |
+} |
+ |
+} // namespace |
+ |
class TestAutofillManager : public AutofillManager { |
public: |
TestAutofillManager(AutofillDriver* driver, |
@@ -629,6 +769,14 @@ class TestAutofillManager : public AutofillManager { |
return personal_data_->GetCreditCardWithGUID(guid); |
} |
+ std::vector<CreditCard*> GetLocalCreditCards() const { |
+ return personal_data_->GetLocalCreditCards(); |
+ } |
+ |
+ const std::vector<CreditCard*>& GetCreditCards() const { |
+ return personal_data_->GetCreditCards(); |
+ } |
+ |
void AddProfile(std::unique_ptr<AutofillProfile> profile) { |
personal_data_->AddProfile(std::move(profile)); |
} |
@@ -652,14 +800,21 @@ class TestAutofillManager : public AutofillManager { |
form_structures()->clear(); |
} |
+ void ResetPaymentsClientForCardUpload(const char* server_id) { |
+ TestPaymentsClient* payments_client = |
+ new TestPaymentsClient(driver_->GetURLRequestContext(), this); |
+ payments_client->server_id_ = server_id; |
+ set_payments_client(payments_client); |
+ } |
+ |
private: |
- void OnDidUploadCard(AutofillClient::PaymentsRpcResult result) override { |
+ void OnDidUploadCard(AutofillClient::PaymentsRpcResult result, |
+ const std::string& server_id) override { |
credit_card_was_uploaded_ = true; |
+ AutofillManager::OnDidUploadCard(result, server_id); |
}; |
- // Weak reference. |
- TestPersonalDataManager* personal_data_; |
- |
+ TestPersonalDataManager* personal_data_; // Weak reference. |
bool autofill_enabled_; |
bool credit_card_upload_enabled_; |
bool credit_card_was_uploaded_; |
@@ -673,139 +828,6 @@ class TestAutofillManager : public AutofillManager { |
DISALLOW_COPY_AND_ASSIGN(TestAutofillManager); |
}; |
-class TestAutofillExternalDelegate : public AutofillExternalDelegate { |
- public: |
- explicit TestAutofillExternalDelegate(AutofillManager* autofill_manager, |
- AutofillDriver* autofill_driver) |
- : AutofillExternalDelegate(autofill_manager, autofill_driver), |
- on_query_seen_(false), |
- on_suggestions_returned_seen_(false) {} |
- ~TestAutofillExternalDelegate() override {} |
- |
- void OnQuery(int query_id, |
- const FormData& form, |
- const FormFieldData& field, |
- const gfx::RectF& bounds) override { |
- on_query_seen_ = true; |
- on_suggestions_returned_seen_ = false; |
- } |
- |
- void OnSuggestionsReturned( |
- int query_id, |
- const std::vector<Suggestion>& suggestions) override { |
- on_suggestions_returned_seen_ = true; |
- query_id_ = query_id; |
- suggestions_ = suggestions; |
- } |
- |
- void CheckSuggestions(int expected_page_id, |
- size_t expected_num_suggestions, |
- const Suggestion expected_suggestions[]) { |
- // Ensure that these results are from the most recent query. |
- EXPECT_TRUE(on_suggestions_returned_seen_); |
- |
- EXPECT_EQ(expected_page_id, query_id_); |
- ASSERT_LE(expected_num_suggestions, suggestions_.size()); |
- for (size_t i = 0; i < expected_num_suggestions; ++i) { |
- SCOPED_TRACE(base::StringPrintf("i: %" PRIuS, i)); |
- EXPECT_EQ(expected_suggestions[i].value, suggestions_[i].value); |
- EXPECT_EQ(expected_suggestions[i].label, suggestions_[i].label); |
- EXPECT_EQ(expected_suggestions[i].icon, suggestions_[i].icon); |
- EXPECT_EQ(expected_suggestions[i].frontend_id, |
- suggestions_[i].frontend_id); |
- } |
- ASSERT_EQ(expected_num_suggestions, suggestions_.size()); |
- } |
- |
- // Wrappers around the above GetSuggestions call that take a hardcoded number |
- // of expected results so callsites are cleaner. |
- void CheckSuggestions(int expected_page_id, |
- const Suggestion& suggestion0) { |
- std::vector<Suggestion> suggestion_vector; |
- suggestion_vector.push_back(suggestion0); |
- CheckSuggestions(expected_page_id, 1, &suggestion_vector[0]); |
- } |
- void CheckSuggestions(int expected_page_id, |
- const Suggestion& suggestion0, |
- const Suggestion& suggestion1) { |
- std::vector<Suggestion> suggestion_vector; |
- suggestion_vector.push_back(suggestion0); |
- suggestion_vector.push_back(suggestion1); |
- CheckSuggestions(expected_page_id, 2, &suggestion_vector[0]); |
- } |
- void CheckSuggestions(int expected_page_id, |
- const Suggestion& suggestion0, |
- const Suggestion& suggestion1, |
- const Suggestion& suggestion2) { |
- std::vector<Suggestion> suggestion_vector; |
- suggestion_vector.push_back(suggestion0); |
- suggestion_vector.push_back(suggestion1); |
- suggestion_vector.push_back(suggestion2); |
- CheckSuggestions(expected_page_id, 3, &suggestion_vector[0]); |
- } |
- // Check that the autofill suggestions were sent, and that they match a page |
- // but contain no results. |
- void CheckNoSuggestions(int expected_page_id) { |
- CheckSuggestions(expected_page_id, 0, nullptr); |
- } |
- // Check that the autofill suggestions were sent, and that they match a page |
- // and contain a specific number of suggestions. |
- void CheckSuggestionCount(int expected_page_id, |
- size_t expected_num_suggestions) { |
- // Ensure that these results are from the most recent query. |
- EXPECT_TRUE(on_suggestions_returned_seen_); |
- |
- EXPECT_EQ(expected_page_id, query_id_); |
- ASSERT_EQ(expected_num_suggestions, suggestions_.size()); |
- } |
- |
- bool on_query_seen() const { |
- return on_query_seen_; |
- } |
- |
- bool on_suggestions_returned_seen() const { |
- return on_suggestions_returned_seen_; |
- } |
- |
- private: |
- // Records if OnQuery has been called yet. |
- bool on_query_seen_; |
- |
- // Records if OnSuggestionsReturned has been called after the most recent |
- // call to OnQuery. |
- bool on_suggestions_returned_seen_; |
- |
- // The query id of the most recent Autofill query. |
- int query_id_; |
- |
- // The results returned by the most recent Autofill query. |
- std::vector<Suggestion> suggestions_; |
- |
- DISALLOW_COPY_AND_ASSIGN(TestAutofillExternalDelegate); |
-}; |
- |
-// Finds the specified UKM metric by |name| in the specified UKM |metrics|. |
-const ukm::Entry_Metric* FindMetric( |
- const char* name, |
- const google::protobuf::RepeatedPtrField<ukm::Entry_Metric>& metrics) { |
- for (const auto& metric : metrics) { |
- if (metric.metric_hash() == base::HashMetricName(name)) |
- return &metric; |
- } |
- return nullptr; |
-} |
- |
-// Get Ukm sources from the Ukm service. |
-std::vector<const ukm::UkmSource*> GetUkmSources(ukm::TestUkmService* service) { |
- std::vector<const ukm::UkmSource*> sources; |
- for (const auto& kv : service->GetSources()) |
- sources.push_back(kv.second.get()); |
- |
- return sources; |
-} |
- |
-} // namespace |
- |
class AutofillManagerTest : public testing::Test { |
public: |
AutofillManagerTest() : field_trial_list_(nullptr) {} |
@@ -843,6 +865,7 @@ class AutofillManagerTest : public testing::Test { |
// need to care about removing self as an observer in destruction. |
personal_data_.set_database(scoped_refptr<AutofillWebDataService>(NULL)); |
personal_data_.SetPrefService(NULL); |
+ personal_data_.ClearCreditCards(); |
request_context_ = nullptr; |
} |
@@ -870,7 +893,9 @@ class AutofillManagerTest : public testing::Test { |
void FormSubmitted(const FormData& form) { |
autofill_manager_->ResetRunLoop(); |
- if (autofill_manager_->OnWillSubmitForm(form, base::TimeTicks::Now())) |
+ if (autofill_manager_->OnWillSubmitForm(form, base::TimeTicks::Now()) && |
+ (!personal_data_.GetProfiles().empty() || |
+ !personal_data_.GetCreditCards().empty())) |
autofill_manager_->WaitForAsyncUploadProcess(); |
autofill_manager_->OnFormSubmitted(form); |
} |
@@ -1119,7 +1144,6 @@ class AutofillManagerTest : public testing::Test { |
std::unique_ptr<TestAutofillManager> autofill_manager_; |
std::unique_ptr<TestAutofillExternalDelegate> external_delegate_; |
scoped_refptr<net::TestURLRequestContextGetter> request_context_; |
- TestPaymentsClient* payments_client_; |
TestAutofillDownloadManager* download_manager_; |
TestPersonalDataManager personal_data_; |
base::FieldTrialList field_trial_list_; |
@@ -1778,7 +1802,6 @@ TEST_F(AutofillManagerTest, |
// are no credit card suggestions and the promo is active. See the tests in |
// AutofillExternalDelegateTest that test whether the promo is added. |
TEST_F(AutofillManagerTest, GetCreditCardSuggestions_OnlySigninPromo) { |
- // Make sure there are no credit cards. |
personal_data_.ClearCreditCards(); |
// Set up our form data. |
@@ -2335,7 +2358,6 @@ TEST_F(AutofillManagerTest, FillCreditCardForm_YearNoMonth) { |
TEST_F(AutofillManagerTest, FillCreditCardForm_YearMonth) { |
// Same as the SetUp(), but generate 4 credit cards with year month |
// combination. |
- personal_data_.ClearCreditCards(); |
personal_data_.CreateTestCreditCardsYearAndMonth("2999", "04"); |
// Set up our form data. |
FormData form; |
@@ -4583,6 +4605,7 @@ TEST_F(AutofillManagerTest, FillInUpdatedExpirationDate) { |
#endif |
TEST_F(AutofillManagerTest, MAYBE_UploadCreditCard) { |
EnableUkmLogging(); |
+ personal_data_.ClearCreditCards(); |
personal_data_.ClearAutofillProfiles(); |
autofill_manager_->set_credit_card_upload_enabled(true); |
@@ -4614,6 +4637,9 @@ TEST_F(AutofillManagerTest, MAYBE_UploadCreditCard) { |
FormSubmitted(credit_card_form); |
EXPECT_TRUE(autofill_manager_->credit_card_was_uploaded()); |
+ // Server did not send a server_id, expect copy of card is not stored. |
+ EXPECT_TRUE(autofill_manager_->GetCreditCards().empty()); |
+ |
// Verify that the correct histogram entry (and only that) was logged. |
histogram_tester.ExpectUniqueSample("Autofill.CardUploadDecisionExpanded", |
AutofillMetrics::UPLOAD_OFFERED, 1); |
@@ -4623,6 +4649,58 @@ TEST_F(AutofillManagerTest, MAYBE_UploadCreditCard) { |
// TODO(crbug.com/666704): Flaky on android_n5x_swarming_rel bot. |
#if defined(OS_ANDROID) |
+#define MAYBE_UploadCreditCardAndSaveCopy DISABLED_UploadCreditCardAndSaveCopy |
+#else |
+#define MAYBE_UploadCreditCardAndSaveCopy UploadCreditCardAndSaveCopy |
+#endif |
+TEST_F(AutofillManagerTest, MAYBE_UploadCreditCardAndSaveCopy) { |
+ personal_data_.ClearCreditCards(); |
+ personal_data_.ClearAutofillProfiles(); |
+ autofill_manager_->set_credit_card_upload_enabled(true); |
+ |
+ const char* const server_id = "InstrumentData:1234"; |
+ autofill_manager_->ResetPaymentsClientForCardUpload(server_id); |
+ |
+ // Create, fill and submit an address form in order to establish a recent |
+ // profile which can be selected for the upload request. |
+ FormData address_form; |
+ test::CreateTestAddressFormData(&address_form); |
+ FormsSeen(std::vector<FormData>(1, address_form)); |
+ |
+ ManuallyFillAddressForm("Flo", "Master", "77401", "US", &address_form); |
+ FormSubmitted(address_form); |
+ |
+ // Set up our credit card form data. |
+ FormData credit_card_form; |
+ CreateTestCreditCardFormData(&credit_card_form, true, false); |
+ FormsSeen(std::vector<FormData>(1, credit_card_form)); |
+ |
+ // Edit the data, and submit. |
+ const char* const card_number = "4111111111111111"; |
+ credit_card_form.fields[0].value = ASCIIToUTF16("Flo Master"); |
+ credit_card_form.fields[1].value = ASCIIToUTF16(card_number); |
+ credit_card_form.fields[2].value = ASCIIToUTF16("11"); |
+ credit_card_form.fields[3].value = ASCIIToUTF16("2017"); |
+ credit_card_form.fields[4].value = ASCIIToUTF16("123"); |
+ |
+ FormSubmitted(credit_card_form); |
+ |
+ EXPECT_TRUE(autofill_manager_->credit_card_was_uploaded()); |
+ EXPECT_TRUE(autofill_manager_->GetLocalCreditCards().empty()); |
+ ASSERT_EQ(1U, autofill_manager_->GetCreditCards().size()); |
+ const CreditCard* const saved_card = autofill_manager_->GetCreditCards()[0]; |
+ EXPECT_EQ(CreditCard::OK, saved_card->GetServerStatus()); |
+ EXPECT_EQ(base::ASCIIToUTF16("1111"), saved_card->LastFourDigits()); |
+ EXPECT_EQ(kVisaCard, saved_card->type()); |
+ EXPECT_EQ(11, saved_card->expiration_month()); |
+ EXPECT_EQ(2017, saved_card->expiration_year()); |
+ EXPECT_EQ(server_id, saved_card->server_id()); |
+ EXPECT_EQ(CreditCard::FULL_SERVER_CARD, saved_card->record_type()); |
+ EXPECT_EQ(base::ASCIIToUTF16(card_number), saved_card->number()); |
+} |
+ |
+// TODO(crbug.com/666704): Flaky on android_n5x_swarming_rel bot. |
+#if defined(OS_ANDROID) |
#define MAYBE_UploadCreditCard_FeatureNotEnabled DISABLED_UploadCreditCard_FeatureNotEnabled |
#else |
#define MAYBE_UploadCreditCard_FeatureNotEnabled UploadCreditCard_FeatureNotEnabled |