// 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 <memory>
#include <vector>

#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/metrics/user_action_tester.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "components/autofill/core/browser/autofill_experiments.h"
#include "components/autofill/core/browser/autofill_external_delegate.h"
#include "components/autofill/core/browser/autofill_manager.h"
#include "components/autofill/core/browser/autofill_metrics.h"
#include "components/autofill/core/browser/autofill_test_utils.h"
#include "components/autofill/core/browser/popup_item_ids.h"
#include "components/autofill/core/browser/suggestion_test_helpers.h"
#include "components/autofill/core/browser/test_autofill_client.h"
#include "components/autofill/core/browser/test_autofill_driver.h"
#include "components/autofill/core/common/autofill_features.h"
#include "components/autofill/core/common/autofill_switches.h"
#include "components/autofill/core/common/form_data.h"
#include "components/autofill/core/common/form_field_data.h"
#include "components/autofill/core/common/password_form_fill_data.h"
#include "components/strings/grit/components_strings.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/geometry/rect.h"

using autofill::features::kAutofillDownstreamUseGooglePayBrandingOniOS;
using base::ASCIIToUTF16;
using testing::_;

namespace autofill {

namespace {

// A constant value to use as the Autofill query ID.
const int kQueryId = 5;

// A constant value to use as an Autofill profile ID.
const int kAutofillProfileId = 1;

class MockAutofillDriver : public TestAutofillDriver {
 public:
  MockAutofillDriver() {}
  // Mock methods to enable testability.
  MOCK_METHOD1(RendererShouldAcceptDataListSuggestion,
               void(const base::string16&));
  MOCK_METHOD0(RendererShouldClearFilledSection, void());
  MOCK_METHOD0(RendererShouldClearPreviewedForm, void());
  MOCK_METHOD1(RendererShouldFillFieldWithValue, void(const base::string16&));
  MOCK_METHOD1(RendererShouldPreviewFieldWithValue,
               void(const base::string16&));

 private:
  DISALLOW_COPY_AND_ASSIGN(MockAutofillDriver);
};

class MockAutofillClient : public TestAutofillClient {
 public:
  MockAutofillClient() {}

  MOCK_METHOD1(ScanCreditCard,
               void(const CreditCardScanCallback& callbacK));

  MOCK_METHOD5(ShowAutofillPopup,
               void(const gfx::RectF& element_bounds,
                    base::i18n::TextDirection text_direction,
                    const std::vector<Suggestion>& suggestions,
                    bool autoselect_first_suggestion,
                    base::WeakPtr<AutofillPopupDelegate> delegate));

  MOCK_METHOD2(UpdateAutofillPopupDataListValues,
               void(const std::vector<base::string16>& values,
                    const std::vector<base::string16>& lables));

  MOCK_METHOD0(HideAutofillPopup, void());

  MOCK_METHOD1(ExecuteCommand, void(int));

 private:
  DISALLOW_COPY_AND_ASSIGN(MockAutofillClient);
};

class MockAutofillManager : public AutofillManager {
 public:
  MockAutofillManager(AutofillDriver* driver, MockAutofillClient* client)
      // Force to use the constructor designated for unit test, but we don't
      // really need personal_data in this test so we pass a NULL pointer.
      : AutofillManager(driver, client, nullptr) {}
  ~MockAutofillManager() override {}

  PopupType GetPopupType(const FormData& form,
                         const FormFieldData& field) override {
    return PopupType::kPersonalInformation;
  }

  MOCK_METHOD2(ShouldShowScanCreditCard,
               bool(const FormData& form, const FormFieldData& field));

  MOCK_METHOD2(ShouldShowCreditCardSigninPromo,
               bool(const FormData& form, const FormFieldData& field));

  MOCK_METHOD5(FillOrPreviewForm,
               void(AutofillDriver::RendererFormDataAction action,
                    int query_id,
                    const FormData& form,
                    const FormFieldData& field,
                    int unique_id));

  MOCK_METHOD5(FillCreditCardForm,
               void(int query_id,
                    const FormData& form,
                    const FormFieldData& field,
                    const CreditCard& credit_card,
                    const base::string16& cvc));

 private:
  DISALLOW_COPY_AND_ASSIGN(MockAutofillManager);
};

}  // namespace

class AutofillExternalDelegateUnitTest : public testing::Test {
 protected:
  void SetUp() override {
    autofill_driver_ =
        std::make_unique<testing::NiceMock<MockAutofillDriver>>();
    autofill_manager_ = std::make_unique<MockAutofillManager>(
        autofill_driver_.get(), &autofill_client_);
    external_delegate_ = std::make_unique<AutofillExternalDelegate>(
        autofill_manager_.get(), autofill_driver_.get());
  }

  void TearDown() override {
    // Order of destruction is important as AutofillManager relies on
    // PersonalDataManager to be around when it gets destroyed.
    autofill_manager_.reset();
    external_delegate_.reset();
    autofill_driver_.reset();
  }

  // Issue an OnQuery call with the given |query_id|.
  void IssueOnQuery(int query_id) {
    const FormData form;
    FormFieldData field;
    field.is_focusable = true;
    field.should_autocomplete = true;

    external_delegate_->OnQuery(query_id, form, field, gfx::RectF());
  }

  void IssueOnSuggestionsReturned() {
    std::vector<Suggestion> suggestions;
    suggestions.push_back(Suggestion());
    suggestions[0].frontend_id = kAutofillProfileId;
    external_delegate_->OnSuggestionsReturned(
        kQueryId, suggestions, /*autoselect_first_suggestion=*/false);
  }

  testing::NiceMock<MockAutofillClient> autofill_client_;
  std::unique_ptr<testing::NiceMock<MockAutofillDriver>> autofill_driver_;
  std::unique_ptr<MockAutofillManager> autofill_manager_;
  std::unique_ptr<AutofillExternalDelegate> external_delegate_;

  base::MessageLoop message_loop_;
};

// Test that our external delegate called the virtual methods at the right time.
TEST_F(AutofillExternalDelegateUnitTest, TestExternalDelegateVirtualCalls) {
  IssueOnQuery(kQueryId);

  // The enums must be cast to ints to prevent compile errors on linux_rel.
  auto element_ids = testing::ElementsAre(
      kAutofillProfileId,
#if !defined(OS_ANDROID)
      static_cast<int>(POPUP_ITEM_ID_SEPARATOR),
#endif
      static_cast<int>(POPUP_ITEM_ID_AUTOFILL_OPTIONS));
  EXPECT_CALL(
      autofill_client_,
      ShowAutofillPopup(_, _, SuggestionVectorIdsAre(element_ids), false, _));

  // This should call ShowAutofillPopup.
  std::vector<Suggestion> autofill_item;
  autofill_item.push_back(Suggestion());
  autofill_item[0].frontend_id = kAutofillProfileId;
  external_delegate_->OnSuggestionsReturned(
      kQueryId, autofill_item, /*autoselect_first_suggestion=*/false);

  EXPECT_CALL(*autofill_manager_,
              FillOrPreviewForm(
                  AutofillDriver::FORM_DATA_ACTION_FILL, _, _, _, _));
  EXPECT_CALL(autofill_client_, HideAutofillPopup());

  // This should trigger a call to hide the popup since we've selected an
  // option.
  external_delegate_->DidAcceptSuggestion(autofill_item[0].value,
                                          autofill_item[0].frontend_id,
                                          0);
}

// Test that our external delegate does not add the signin promo and its
// separator in the popup items when there are suggestions.
TEST_F(AutofillExternalDelegateUnitTest,
       TestSigninPromoIsNotAdded_WithSuggestions) {
  EXPECT_CALL(*autofill_manager_, ShouldShowCreditCardSigninPromo(_, _))
      .WillOnce(testing::Return(true));

  IssueOnQuery(kQueryId);

  // The enums must be cast to ints to prevent compile errors on linux_rel.
  auto element_ids =
      testing::ElementsAre(kAutofillProfileId,
#if !defined(OS_ANDROID)
                           static_cast<int>(POPUP_ITEM_ID_SEPARATOR),
#endif
                           static_cast<int>(POPUP_ITEM_ID_AUTOFILL_OPTIONS));

  EXPECT_CALL(
      autofill_client_,
      ShowAutofillPopup(_, _, SuggestionVectorIdsAre(element_ids), false, _));

  base::UserActionTester user_action_tester;

  // This should call ShowAutofillPopup.
  std::vector<Suggestion> autofill_item;
  autofill_item.push_back(Suggestion());
  autofill_item[0].frontend_id = kAutofillProfileId;
  external_delegate_->OnSuggestionsReturned(
      kQueryId, autofill_item, /*autoselect_first_suggestion=*/false);
  EXPECT_EQ(0, user_action_tester.GetActionCount(
                   "Signin_Impression_FromAutofillDropdown"));

  EXPECT_CALL(
      *autofill_manager_,
      FillOrPreviewForm(AutofillDriver::FORM_DATA_ACTION_FILL, _, _, _, _));
  EXPECT_CALL(autofill_client_, HideAutofillPopup());

  // This should trigger a call to hide the popup since we've selected an
  // option.
  external_delegate_->DidAcceptSuggestion(autofill_item[0].value,
                                          autofill_item[0].frontend_id, 0);
}

// Test that our external delegate properly adds the signin promo and no
// separator in the dropdown, when there are no suggestions.
TEST_F(AutofillExternalDelegateUnitTest,
       TestSigninPromoIsAdded_WithNoSuggestions) {
  EXPECT_CALL(*autofill_manager_, ShouldShowCreditCardSigninPromo(_, _))
      .WillOnce(testing::Return(true));

  IssueOnQuery(kQueryId);

  // The enums must be cast to ints to prevent compile errors on linux_rel.
  auto element_ids = testing::ElementsAre(
      static_cast<int>(POPUP_ITEM_ID_CREDIT_CARD_SIGNIN_PROMO));

  EXPECT_CALL(
      autofill_client_,
      ShowAutofillPopup(_, _, SuggestionVectorIdsAre(element_ids), false, _));

  base::UserActionTester user_action_tester;

  // This should call ShowAutofillPopup.
  std::vector<Suggestion> items;
  external_delegate_->OnSuggestionsReturned(
      kQueryId, items, /*autoselect_first_suggestion=*/false);
  EXPECT_EQ(1, user_action_tester.GetActionCount(
                   "Signin_Impression_FromAutofillDropdown"));

  EXPECT_CALL(autofill_client_,
              ExecuteCommand(autofill::POPUP_ITEM_ID_CREDIT_CARD_SIGNIN_PROMO));
  EXPECT_CALL(autofill_client_, HideAutofillPopup());

  // This should trigger a call to start the signin flow and hide the popup
  // since we've selected the sign-in promo option.
  external_delegate_->DidAcceptSuggestion(
      base::string16(), POPUP_ITEM_ID_CREDIT_CARD_SIGNIN_PROMO, 0);
}

// Test that data list elements for a node will appear in the Autofill popup.
TEST_F(AutofillExternalDelegateUnitTest, ExternalDelegateDataList) {
  IssueOnQuery(kQueryId);

  std::vector<base::string16> data_list_items;
  data_list_items.push_back(base::string16());

  EXPECT_CALL(
      autofill_client_,
      UpdateAutofillPopupDataListValues(data_list_items, data_list_items));

  external_delegate_->SetCurrentDataListValues(data_list_items,
                                               data_list_items);

  // The enums must be cast to ints to prevent compile errors on linux_rel.
  auto element_ids = testing::ElementsAre(
      static_cast<int>(POPUP_ITEM_ID_DATALIST_ENTRY),
#if !defined(OS_ANDROID)
      static_cast<int>(POPUP_ITEM_ID_SEPARATOR),
#endif
      kAutofillProfileId,
#if !defined(OS_ANDROID)
      static_cast<int>(POPUP_ITEM_ID_SEPARATOR),
#endif
      static_cast<int>(POPUP_ITEM_ID_AUTOFILL_OPTIONS));
  EXPECT_CALL(
      autofill_client_,
      ShowAutofillPopup(_, _, SuggestionVectorIdsAre(element_ids), false, _));

  // This should call ShowAutofillPopup.
  std::vector<Suggestion> autofill_item;
  autofill_item.push_back(Suggestion());
  autofill_item[0].frontend_id = kAutofillProfileId;
  external_delegate_->OnSuggestionsReturned(
      kQueryId, autofill_item, /*autoselect_first_suggestion=*/false);

  // Try calling OnSuggestionsReturned with no Autofill values and ensure
  // the datalist items are still shown.
  // The enum must be cast to an int to prevent compile errors on linux_rel.
  EXPECT_CALL(
      autofill_client_,
      ShowAutofillPopup(_, _,
                        SuggestionVectorIdsAre(testing::ElementsAre(
                            static_cast<int>(POPUP_ITEM_ID_DATALIST_ENTRY))),
                        false, _));

  autofill_item.clear();
  external_delegate_->OnSuggestionsReturned(
      kQueryId, autofill_item, /*autoselect_first_suggestion=*/false);
}

// Test that datalist values can get updated while a popup is showing.
TEST_F(AutofillExternalDelegateUnitTest, UpdateDataListWhileShowingPopup) {
  IssueOnQuery(kQueryId);

  EXPECT_CALL(autofill_client_, ShowAutofillPopup(_, _, _, _, _)).Times(0);

  // Make sure just setting the data list values doesn't cause the popup to
  // appear.
  std::vector<base::string16> data_list_items;
  data_list_items.push_back(base::string16());

  EXPECT_CALL(
      autofill_client_,
      UpdateAutofillPopupDataListValues(data_list_items, data_list_items));

  external_delegate_->SetCurrentDataListValues(data_list_items,
                                               data_list_items);

  // The enums must be cast to ints to prevent compile errors on linux_rel.
  auto element_ids = testing::ElementsAre(
      static_cast<int>(POPUP_ITEM_ID_DATALIST_ENTRY),
#if !defined(OS_ANDROID)
      static_cast<int>(POPUP_ITEM_ID_SEPARATOR),
#endif
      kAutofillProfileId,
#if !defined(OS_ANDROID)
      static_cast<int>(POPUP_ITEM_ID_SEPARATOR),
#endif
      static_cast<int>(POPUP_ITEM_ID_AUTOFILL_OPTIONS));
  EXPECT_CALL(
      autofill_client_,
      ShowAutofillPopup(_, _, SuggestionVectorIdsAre(element_ids), false, _));

  // Ensure the popup is displayed.
  std::vector<Suggestion> autofill_item;
  autofill_item.push_back(Suggestion());
  autofill_item[0].frontend_id = kAutofillProfileId;
  external_delegate_->OnSuggestionsReturned(
      kQueryId, autofill_item, /*autoselect_first_suggestion=*/false);

  // This would normally get called from ShowAutofillPopup, but it is mocked so
  // we need to call OnPopupShown ourselves.
  external_delegate_->OnPopupShown();

  // Update the current data list and ensure the popup is updated.
  data_list_items.push_back(base::string16());

  // The enums must be cast to ints to prevent compile errors on linux_rel.
  EXPECT_CALL(
      autofill_client_,
      UpdateAutofillPopupDataListValues(data_list_items, data_list_items));

  external_delegate_->SetCurrentDataListValues(data_list_items,
                                               data_list_items);
}

// Test that we _don't_ de-dupe autofill values against datalist values. We
// keep both with a separator.
TEST_F(AutofillExternalDelegateUnitTest, DuplicateAutofillDatalistValues) {
  IssueOnQuery(kQueryId);

  std::vector<base::string16> data_list_items;
  data_list_items.push_back(base::ASCIIToUTF16("Rick"));
  data_list_items.push_back(base::ASCIIToUTF16("Deckard"));

  EXPECT_CALL(autofill_client_, UpdateAutofillPopupDataListValues(
                                    data_list_items, data_list_items));

  external_delegate_->SetCurrentDataListValues(data_list_items,
                                               data_list_items);

  // The enums must be cast to ints to prevent compile errors on linux_rel.
  auto element_ids =
      testing::ElementsAre(static_cast<int>(POPUP_ITEM_ID_DATALIST_ENTRY),
                           static_cast<int>(POPUP_ITEM_ID_DATALIST_ENTRY),
#if !defined(OS_ANDROID)
                           static_cast<int>(POPUP_ITEM_ID_SEPARATOR),
#endif
                           kAutofillProfileId,
#if !defined(OS_ANDROID)
                           static_cast<int>(POPUP_ITEM_ID_SEPARATOR),
#endif
                           static_cast<int>(POPUP_ITEM_ID_AUTOFILL_OPTIONS));
  EXPECT_CALL(
      autofill_client_,
      ShowAutofillPopup(_, _, SuggestionVectorIdsAre(element_ids), false, _));

  // Have an Autofill item that is identical to one of the datalist entries.
  std::vector<Suggestion> autofill_item;
  autofill_item.push_back(Suggestion());
  autofill_item[0].value = ASCIIToUTF16("Rick");
  autofill_item[0].frontend_id = kAutofillProfileId;
  external_delegate_->OnSuggestionsReturned(
      kQueryId, autofill_item, /*autoselect_first_suggestion=*/false);
}

// Test that we de-dupe autocomplete values against datalist values, keeping the
// latter in case of a match.
TEST_F(AutofillExternalDelegateUnitTest, DuplicateAutocompleteDatalistValues) {
  IssueOnQuery(kQueryId);

  std::vector<base::string16> data_list_items;
  data_list_items.push_back(base::ASCIIToUTF16("Rick"));
  data_list_items.push_back(base::ASCIIToUTF16("Deckard"));

  EXPECT_CALL(autofill_client_, UpdateAutofillPopupDataListValues(
                                    data_list_items, data_list_items));

  external_delegate_->SetCurrentDataListValues(data_list_items,
                                               data_list_items);

  // The enums must be cast to ints to prevent compile errors on linux_rel.
  auto element_ids = testing::ElementsAre(
      // We are expecting only two data list entries.
      static_cast<int>(POPUP_ITEM_ID_DATALIST_ENTRY),
      static_cast<int>(POPUP_ITEM_ID_DATALIST_ENTRY),
#if !defined(OS_ANDROID)
      static_cast<int>(POPUP_ITEM_ID_SEPARATOR),
#endif
      static_cast<int>(POPUP_ITEM_ID_AUTOCOMPLETE_ENTRY));
  EXPECT_CALL(
      autofill_client_,
      ShowAutofillPopup(_, _, SuggestionVectorIdsAre(element_ids), false, _));

  // Have an Autocomplete item that is identical to one of the datalist entries
  // and one that is distinct.
  std::vector<Suggestion> autocomplete_items;
  autocomplete_items.push_back(Suggestion());
  autocomplete_items[0].value = ASCIIToUTF16("Rick");
  autocomplete_items[0].frontend_id = POPUP_ITEM_ID_AUTOCOMPLETE_ENTRY;
  autocomplete_items.push_back(Suggestion());
  autocomplete_items[1].value = ASCIIToUTF16("Cain");
  autocomplete_items[1].frontend_id = POPUP_ITEM_ID_AUTOCOMPLETE_ENTRY;
  external_delegate_->OnSuggestionsReturned(
      kQueryId, autocomplete_items, /*autoselect_first_suggestion=*/false);
}

// Test that the Autofill popup is able to display warnings explaining why
// Autofill is disabled for a website.
// Regression test for http://crbug.com/247880
TEST_F(AutofillExternalDelegateUnitTest, AutofillWarnings) {
  IssueOnQuery(kQueryId);

  // The enums must be cast to ints to prevent compile errors on linux_rel.
  EXPECT_CALL(
      autofill_client_,
      ShowAutofillPopup(
          _, _,
          SuggestionVectorIdsAre(testing::ElementsAre(static_cast<int>(
              POPUP_ITEM_ID_INSECURE_CONTEXT_PAYMENT_DISABLED_MESSAGE))),
          false, _));

  // This should call ShowAutofillPopup.
  std::vector<Suggestion> autofill_item;
  autofill_item.push_back(Suggestion());
  autofill_item[0].frontend_id =
      POPUP_ITEM_ID_INSECURE_CONTEXT_PAYMENT_DISABLED_MESSAGE;
  external_delegate_->OnSuggestionsReturned(
      kQueryId, autofill_item, /*autoselect_first_suggestion=*/false);
}

// Test that Autofill warnings are removed if there are also autocomplete
// entries in the vector.
TEST_F(AutofillExternalDelegateUnitTest,
       AutofillWarningsNotShown_WithSuggestions) {
  IssueOnQuery(kQueryId);

  // The enums must be cast to ints to prevent compile errors on linux_rel.
  EXPECT_CALL(autofill_client_,
              ShowAutofillPopup(
                  _, _,
                  SuggestionVectorIdsAre(testing::ElementsAre(
                      static_cast<int>(POPUP_ITEM_ID_AUTOCOMPLETE_ENTRY))),
                  false, _));

  // This should call ShowAutofillPopup.
  std::vector<Suggestion> suggestions;
  suggestions.push_back(Suggestion());
  suggestions[0].frontend_id =
      POPUP_ITEM_ID_INSECURE_CONTEXT_PAYMENT_DISABLED_MESSAGE;
  suggestions.push_back(Suggestion());
  suggestions[1].value = ASCIIToUTF16("Rick");
  suggestions[1].frontend_id = POPUP_ITEM_ID_AUTOCOMPLETE_ENTRY;
  external_delegate_->OnSuggestionsReturned(
      kQueryId, suggestions, /*autoselect_first_suggestion=*/false);
}

// Test that the Autofill delegate doesn't try and fill a form with a
// negative unique id.
TEST_F(AutofillExternalDelegateUnitTest, ExternalDelegateInvalidUniqueId) {
  // Ensure it doesn't try to preview the negative id.
  EXPECT_CALL(*autofill_manager_, FillOrPreviewForm(_, _, _, _, _)).Times(0);
  EXPECT_CALL(*autofill_driver_, RendererShouldClearPreviewedForm()).Times(1);
  external_delegate_->DidSelectSuggestion(base::string16(), -1);

  // Ensure it doesn't try to fill the form in with the negative id.
  EXPECT_CALL(autofill_client_, HideAutofillPopup());
  EXPECT_CALL(*autofill_manager_, FillOrPreviewForm(_, _, _, _, _)).Times(0);
  external_delegate_->DidAcceptSuggestion(base::string16(), -1, 0);
}

// Test that the ClearPreview call is only sent if the form was being previewed
// (i.e. it isn't autofilling a password).
TEST_F(AutofillExternalDelegateUnitTest, ExternalDelegateClearPreviewedForm) {
  // Ensure selecting a new password entries or Autofill entries will
  // cause any previews to get cleared.
  EXPECT_CALL(*autofill_driver_, RendererShouldClearPreviewedForm()).Times(1);
  external_delegate_->DidSelectSuggestion(ASCIIToUTF16("baz foo"),
                                          POPUP_ITEM_ID_PASSWORD_ENTRY);
  EXPECT_CALL(*autofill_driver_, RendererShouldClearPreviewedForm()).Times(1);
  EXPECT_CALL(*autofill_manager_,
              FillOrPreviewForm(
                  AutofillDriver::FORM_DATA_ACTION_PREVIEW, _, _, _, _));
  external_delegate_->DidSelectSuggestion(ASCIIToUTF16("baz foo"), 1);

  // Ensure selecting an autocomplete entry will cause any previews to
  // get cleared.
  EXPECT_CALL(*autofill_driver_, RendererShouldClearPreviewedForm()).Times(1);
  EXPECT_CALL(*autofill_driver_, RendererShouldPreviewFieldWithValue(
                                     ASCIIToUTF16("baz foo")));
  external_delegate_->DidSelectSuggestion(ASCIIToUTF16("baz foo"),
                                          POPUP_ITEM_ID_AUTOCOMPLETE_ENTRY);
}

// Test that the popup is hidden once we are done editing the autofill field.
TEST_F(AutofillExternalDelegateUnitTest,
       ExternalDelegateHidePopupAfterEditing) {
  EXPECT_CALL(autofill_client_, ShowAutofillPopup(_, _, _, _, _));
  test::GenerateTestAutofillPopup(external_delegate_.get());

  EXPECT_CALL(autofill_client_, HideAutofillPopup());
  external_delegate_->DidEndTextFieldEditing();
}

// Test that the driver is directed to accept the data list after being notified
// that the user accepted the data list suggestion.
TEST_F(AutofillExternalDelegateUnitTest,
       ExternalDelegateAcceptDatalistSuggestion) {
  EXPECT_CALL(autofill_client_, HideAutofillPopup());
  base::string16 dummy_string(ASCIIToUTF16("baz qux"));
  EXPECT_CALL(*autofill_driver_,
              RendererShouldAcceptDataListSuggestion(dummy_string));
  external_delegate_->DidAcceptSuggestion(dummy_string,
                                          POPUP_ITEM_ID_DATALIST_ENTRY,
                                          0);
}

// Test that an accepted autofill suggestion will fill the form and log the
// proper metric.
TEST_F(AutofillExternalDelegateUnitTest,
       ExternalDelegateAcceptAutofillSuggestion) {
  EXPECT_CALL(autofill_client_, HideAutofillPopup());
  base::string16 dummy_string(ASCIIToUTF16("John Legend"));
  EXPECT_CALL(*autofill_manager_,
              FillOrPreviewForm(
                  AutofillDriver::FORM_DATA_ACTION_FILL, _, _, _,
                  kAutofillProfileId));
  base::HistogramTester histogram;
  external_delegate_->DidAcceptSuggestion(dummy_string,
                                          kAutofillProfileId,
                                          2);  // Row 2
  histogram.ExpectUniqueSample("Autofill.SuggestionAcceptedIndex", 2, 1);
}

// Test that the driver is directed to clear the form after being notified that
// the user accepted the suggestion to clear the form.
TEST_F(AutofillExternalDelegateUnitTest, ExternalDelegateClearForm) {
  EXPECT_CALL(autofill_client_, HideAutofillPopup());
  EXPECT_CALL(*autofill_driver_, RendererShouldClearFilledSection());

  external_delegate_->DidAcceptSuggestion(base::string16(),
                                          POPUP_ITEM_ID_CLEAR_FORM,
                                          0);
}

// Test that autofill client will scan a credit card after use accepted the
// suggestion to scan a credit card.
TEST_F(AutofillExternalDelegateUnitTest, ScanCreditCardMenuItem) {
  EXPECT_CALL(autofill_client_, ScanCreditCard(_));
  EXPECT_CALL(autofill_client_, HideAutofillPopup());
  external_delegate_->DidAcceptSuggestion(base::string16(),
                                          POPUP_ITEM_ID_SCAN_CREDIT_CARD,
                                          0);
}

TEST_F(AutofillExternalDelegateUnitTest, ScanCreditCardPromptMetricsTest) {
  // Log that the scan card item was shown, although nothing was selected.
  {
    EXPECT_CALL(*autofill_manager_, ShouldShowScanCreditCard(_, _))
        .WillOnce(testing::Return(true));
    base::HistogramTester histogram;
    IssueOnQuery(kQueryId);
    IssueOnSuggestionsReturned();
    external_delegate_->OnPopupShown();
    histogram.ExpectUniqueSample("Autofill.ScanCreditCardPrompt",
                                 AutofillMetrics::SCAN_CARD_ITEM_SHOWN, 1);
  }
  // Log that the scan card item was selected.
  {
    EXPECT_CALL(*autofill_manager_, ShouldShowScanCreditCard(_, _))
        .WillOnce(testing::Return(true));
    base::HistogramTester histogram;
    IssueOnQuery(kQueryId);
    IssueOnSuggestionsReturned();
    external_delegate_->OnPopupShown();
    external_delegate_->DidAcceptSuggestion(base::string16(),
                                            POPUP_ITEM_ID_SCAN_CREDIT_CARD,
                                            0);
    histogram.ExpectBucketCount("Autofill.ScanCreditCardPrompt",
                                AutofillMetrics::SCAN_CARD_ITEM_SHOWN, 1);
    histogram.ExpectBucketCount("Autofill.ScanCreditCardPrompt",
                                AutofillMetrics::SCAN_CARD_ITEM_SELECTED, 1);
    histogram.ExpectBucketCount("Autofill.ScanCreditCardPrompt",
                                AutofillMetrics::SCAN_CARD_OTHER_ITEM_SELECTED,
                                0);
  }
  // Log that something else was selected.
  {
    EXPECT_CALL(*autofill_manager_, ShouldShowScanCreditCard(_, _))
        .WillOnce(testing::Return(true));
    base::HistogramTester histogram;
    IssueOnQuery(kQueryId);
    IssueOnSuggestionsReturned();
    external_delegate_->OnPopupShown();
    external_delegate_->DidAcceptSuggestion(base::string16(),
                                            POPUP_ITEM_ID_CLEAR_FORM,
                                            0);
    histogram.ExpectBucketCount("Autofill.ScanCreditCardPrompt",
                                AutofillMetrics::SCAN_CARD_ITEM_SHOWN, 1);
    histogram.ExpectBucketCount("Autofill.ScanCreditCardPrompt",
                                AutofillMetrics::SCAN_CARD_ITEM_SELECTED, 0);
    histogram.ExpectBucketCount("Autofill.ScanCreditCardPrompt",
                                AutofillMetrics::SCAN_CARD_OTHER_ITEM_SELECTED,
                                1);
  }
  // Nothing is logged when the item isn't shown.
  {
    EXPECT_CALL(*autofill_manager_, ShouldShowScanCreditCard(_, _))
        .WillOnce(testing::Return(false));
    base::HistogramTester histogram;
    IssueOnQuery(kQueryId);
    IssueOnSuggestionsReturned();
    external_delegate_->OnPopupShown();
    histogram.ExpectTotalCount("Autofill.ScanCreditCardPrompt", 0);
  }
}

// Test that autofill client will start the signin flow after the user accepted
// the suggestion to sign in.
TEST_F(AutofillExternalDelegateUnitTest, SigninPromoMenuItem) {
  EXPECT_CALL(autofill_client_,
              ExecuteCommand(autofill::POPUP_ITEM_ID_CREDIT_CARD_SIGNIN_PROMO));
  EXPECT_CALL(autofill_client_, HideAutofillPopup());
  external_delegate_->DidAcceptSuggestion(
      base::string16(), POPUP_ITEM_ID_CREDIT_CARD_SIGNIN_PROMO, 0);
}

MATCHER_P(CreditCardMatches, card, "") {
  return !arg.Compare(card);
}

// Test that autofill manager will fill the credit card form after user scans a
// credit card.
TEST_F(AutofillExternalDelegateUnitTest, FillCreditCardForm) {
  CreditCard card;
  test::SetCreditCardInfo(&card, "Alice", "4111", "1", "3000", "1");
  EXPECT_CALL(*autofill_manager_,
      FillCreditCardForm(_, _, _, CreditCardMatches(card), base::string16()));
  external_delegate_->OnCreditCardScanned(card);
}

TEST_F(AutofillExternalDelegateUnitTest, IgnoreAutocompleteOffForAutofill) {
  const FormData form;
  FormFieldData field;
  field.is_focusable = true;
  field.should_autocomplete = false;

  external_delegate_->OnQuery(kQueryId, form, field, gfx::RectF());

  std::vector<Suggestion> autofill_items;
  autofill_items.push_back(Suggestion());
  autofill_items[0].frontend_id = POPUP_ITEM_ID_AUTOCOMPLETE_ENTRY;

  // Ensure the popup tries to show itself, despite autocomplete="off".
  EXPECT_CALL(autofill_client_, ShowAutofillPopup(_, _, _, _, _));
  EXPECT_CALL(autofill_client_, HideAutofillPopup()).Times(0);

  external_delegate_->OnSuggestionsReturned(
      kQueryId, autofill_items, /*autoselect_first_suggestion=*/false);
}

TEST_F(AutofillExternalDelegateUnitTest, ExternalDelegateFillFieldWithValue) {
  EXPECT_CALL(autofill_client_, HideAutofillPopup());
  base::string16 dummy_string(ASCIIToUTF16("baz foo"));
  EXPECT_CALL(*autofill_driver_,
              RendererShouldFillFieldWithValue(dummy_string));
  base::HistogramTester histogram_tester;
  external_delegate_->DidAcceptSuggestion(dummy_string,
                                          POPUP_ITEM_ID_AUTOCOMPLETE_ENTRY,
                                          0);
  histogram_tester.ExpectUniqueSample(
      "Autofill.SuggestionAcceptedIndex.Autocomplete", 0, 1);
}

TEST_F(AutofillExternalDelegateUnitTest, ShouldShowGooglePayIcon) {
  IssueOnQuery(kQueryId);

  auto element_icons = testing::ElementsAre(
#if !defined(OS_ANDROID)
      base::string16(),
#endif
      base::string16(), base::ASCIIToUTF16("googlePay"));
  EXPECT_CALL(autofill_client_,
              ShowAutofillPopup(_, _, SuggestionVectorIconsAre(element_icons),
                                false, _));

  std::vector<Suggestion> autofill_item;
  autofill_item.push_back(Suggestion());
  autofill_item[0].frontend_id = kAutofillProfileId;

  // This should call ShowAutofillPopup.
  external_delegate_->OnSuggestionsReturned(
      kQueryId, autofill_item, /*autoselect_first_suggestion=*/false, true);
}

#if defined(OS_IOS)
TEST_F(AutofillExternalDelegateUnitTest, ShouldShowGooglePayIconOniOS) {
  // Turn on feature flag.
  base::test::ScopedFeatureList scoped_feature_list_;
  scoped_feature_list_.InitAndEnableFeature(
      kAutofillDownstreamUseGooglePayBrandingOniOS);
  IssueOnQuery(kQueryId);

  auto element_icons =
      testing::ElementsAre(base::ASCIIToUTF16("googlePay"), base::string16(),
                           base::string16(), base::ASCIIToUTF16("googlePay"));
  EXPECT_CALL(autofill_client_,
              ShowAutofillPopup(_, _, SuggestionVectorIconsAre(element_icons),
                                false, _));

  std::vector<Suggestion> autofill_item;
  autofill_item.push_back(Suggestion());
  autofill_item[0].frontend_id = kAutofillProfileId;

  // This should call ShowAutofillPopup.
  external_delegate_->OnSuggestionsReturned(
      kQueryId, autofill_item, /*autoselect_first_suggestion=*/false, true);
}

TEST_F(AutofillExternalDelegateUnitTest,
       ShouldNotShowGooglePayIconOniOSIfExperimentOff) {
  // Turn on feature flag.
  base::test::ScopedFeatureList scoped_feature_list_;
  scoped_feature_list_.InitAndDisableFeature(
      kAutofillDownstreamUseGooglePayBrandingOniOS);
  IssueOnQuery(kQueryId);

  auto element_icons = testing::ElementsAre(
      base::string16(), base::string16(),
      base::string16() /* Autofill setting item does not have icon. */);
  EXPECT_CALL(autofill_client_,
              ShowAutofillPopup(_, _, SuggestionVectorIconsAre(element_icons),
                                false, _));

  std::vector<Suggestion> autofill_item;
  autofill_item.push_back(Suggestion());
  autofill_item[0].frontend_id = kAutofillProfileId;

  // This should call ShowAutofillPopup.
  external_delegate_->OnSuggestionsReturned(
      kQueryId, autofill_item, /*autoselect_first_suggestion=*/false, false);
}
#endif  // defined(OS_IOS)

TEST_F(AutofillExternalDelegateUnitTest,
       ShouldNotShowGooglePayIconIfSuggestionsContainLocalCards) {
  IssueOnQuery(kQueryId);

  auto element_icons = testing::ElementsAre(
#if !defined(OS_ANDROID)
      base::string16(),
#endif
      base::string16(),
      base::string16() /* Autofill setting item does not have icon. */);
  EXPECT_CALL(autofill_client_,
              ShowAutofillPopup(_, _, SuggestionVectorIconsAre(element_icons),
                                false, _));

  std::vector<Suggestion> autofill_item;
  autofill_item.push_back(Suggestion());
  autofill_item[0].frontend_id = kAutofillProfileId;

  // This should call ShowAutofillPopup.
  external_delegate_->OnSuggestionsReturned(
      kQueryId, autofill_item, /*autoselect_first_suggestion=*/false, false);
}

TEST_F(AutofillExternalDelegateUnitTest, ShouldUseNewSettingName) {
  IssueOnQuery(kQueryId);

  auto element_values = testing::ElementsAre(
#if !defined(OS_ANDROID)
      base::string16(),
#endif
      base::string16(), l10n_util::GetStringUTF16(IDS_AUTOFILL_MANAGE));
  EXPECT_CALL(autofill_client_,
              ShowAutofillPopup(_, _, SuggestionVectorValuesAre(element_values),
                                false, _));

  std::vector<Suggestion> autofill_item;
  autofill_item.push_back(Suggestion());
  autofill_item[0].frontend_id = kAutofillProfileId;

  // This should call ShowAutofillPopup.
  external_delegate_->OnSuggestionsReturned(
      kQueryId, autofill_item, /*autoselect_first_suggestion=*/false);
}

#if !defined(OS_ANDROID)
// Test that the delegate includes a separator between the content rows and the
// footer, if and only if the kAutofillExpandedPopupViews feature is disabled.
TEST_F(AutofillExternalDelegateUnitTest, IncludeFooterSeparatorForOldUIOnly) {
  // The guts of the test. This will be run once with the feature enabled,
  // expecting not to find a separator, and a second time with the feature
  // disabled, expecting to find a separator.
  auto tester = [this](bool enabled, auto element_ids) {
    base::test::ScopedFeatureList scoped_feature_list;

    if (enabled) {
      scoped_feature_list.InitAndEnableFeature(
          autofill::kAutofillExpandedPopupViews);
    } else {
      scoped_feature_list.InitAndDisableFeature(
          autofill::kAutofillExpandedPopupViews);
    }

    IssueOnQuery(kQueryId);

    EXPECT_CALL(
        autofill_client_,
        ShowAutofillPopup(_, _, SuggestionVectorIdsAre(element_ids), false, _));

    std::vector<Suggestion> autofill_item;
    autofill_item.push_back(Suggestion());
    autofill_item[0].frontend_id = kAutofillProfileId;
    external_delegate_->OnSuggestionsReturned(
        kQueryId, autofill_item, /*autoselect_first_suggestion=*/false);
  };

  tester(false,
         testing::ElementsAre(
             kAutofillProfileId, static_cast<int>(POPUP_ITEM_ID_SEPARATOR),
             static_cast<int>(POPUP_ITEM_ID_AUTOFILL_OPTIONS)));

  tester(true, testing::ElementsAre(
                   kAutofillProfileId,
                   static_cast<int>(POPUP_ITEM_ID_AUTOFILL_OPTIONS)));
}
#endif  // !defined(OS_ANDROID)

}  // namespace autofill
