| 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
|
|
|