普通文本  |  2062行  |  76.6 KB

// Copyright (c) 2011 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 <vector>

#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "base/string16.h"
#include "base/string_number_conversions.h"
#include "base/stringprintf.h"
#include "base/tuple.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/autocomplete_history_manager.h"
#include "chrome/browser/autofill/autofill_common_test.h"
#include "chrome/browser/autofill/autofill_manager.h"
#include "chrome/browser/autofill/autofill_profile.h"
#include "chrome/browser/autofill/credit_card.h"
#include "chrome/browser/autofill/personal_data_manager.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "chrome/browser/ui/tab_contents/test_tab_contents_wrapper.h"
#include "chrome/common/autofill_messages.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/testing_profile.h"
#include "content/browser/tab_contents/test_tab_contents.h"
#include "googleurl/src/gurl.h"
#include "grit/generated_resources.h"
#include "ipc/ipc_test_sink.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/l10n/l10n_util.h"
#include "webkit/glue/form_data.h"
#include "webkit/glue/form_field.h"

using webkit_glue::FormData;
using webkit_glue::FormField;

namespace {

// The page ID sent to the AutofillManager from the RenderView, used to send
// an IPC message back to the renderer.
const int kDefaultPageID = 137;

typedef Tuple5<int,
               std::vector<string16>,
               std::vector<string16>,
               std::vector<string16>,
               std::vector<int> > AutofillParam;

class TestPersonalDataManager : public PersonalDataManager {
 public:
  TestPersonalDataManager() {
    CreateTestAutofillProfiles(&web_profiles_);
    CreateTestCreditCards(&credit_cards_);
  }

  MOCK_METHOD1(SaveImportedProfile, void(const AutofillProfile&));

  AutofillProfile* GetProfileWithGUID(const char* guid) {
    for (std::vector<AutofillProfile *>::iterator it = web_profiles_.begin();
         it != web_profiles_.end(); ++it) {
      if (!(*it)->guid().compare(guid))
        return *it;
    }
    return NULL;
  }

  void AddProfile(AutofillProfile* profile) {
    web_profiles_->push_back(profile);
  }

  void AddCreditCard(CreditCard* credit_card) {
    credit_cards_->push_back(credit_card);
  }

  void ClearAutofillProfiles() {
    web_profiles_.reset();
  }

  void ClearCreditCards() {
    credit_cards_.reset();
  }

  void CreateTestCreditCardsYearAndMonth(const char* year, const char* month) {
    ClearCreditCards();
    CreditCard* credit_card = new CreditCard;
    autofill_test::SetCreditCardInfo(credit_card, "Miku Hatsune",
                                     "4234567890654321", // Visa
                                     month, year);
    credit_card->set_guid("00000000-0000-0000-0000-000000000007");
    credit_cards_->push_back(credit_card);
 }

 private:
  void CreateTestAutofillProfiles(ScopedVector<AutofillProfile>* profiles) {
    AutofillProfile* profile = new AutofillProfile;
    autofill_test::SetProfileInfo(profile, "Elvis", "Aaron",
                                  "Presley", "theking@gmail.com", "RCA",
                                  "3734 Elvis Presley Blvd.", "Apt. 10",
                                  "Memphis", "Tennessee", "38116", "USA",
                                  "12345678901", "");
    profile->set_guid("00000000-0000-0000-0000-000000000001");
    profiles->push_back(profile);
    profile = new AutofillProfile;
    autofill_test::SetProfileInfo(profile, "Charles", "Hardin",
                                  "Holley", "buddy@gmail.com", "Decca",
                                  "123 Apple St.", "unit 6", "Lubbock",
                                  "Texas", "79401", "USA", "23456789012",
                                  "");
    profile->set_guid("00000000-0000-0000-0000-000000000002");
    profiles->push_back(profile);
    profile = new AutofillProfile;
    autofill_test::SetProfileInfo(profile, "", "", "", "", "", "", "",
                                  "", "", "", "", "", "");
    profile->set_guid("00000000-0000-0000-0000-000000000003");
    profiles->push_back(profile);
  }

  void CreateTestCreditCards(ScopedVector<CreditCard>* credit_cards) {
    CreditCard* credit_card = new CreditCard;
    autofill_test::SetCreditCardInfo(credit_card, "Elvis Presley",
                                     "4234 5678 9012 3456",  // Visa
                                     "04", "2012");
    credit_card->set_guid("00000000-0000-0000-0000-000000000004");
    credit_cards->push_back(credit_card);

    credit_card = new CreditCard;
    autofill_test::SetCreditCardInfo(credit_card, "Buddy Holly",
                                     "5187654321098765",  // Mastercard
                                     "10", "2014");
    credit_card->set_guid("00000000-0000-0000-0000-000000000005");
    credit_cards->push_back(credit_card);

    credit_card = new CreditCard;
    autofill_test::SetCreditCardInfo(credit_card, "", "", "", "");
    credit_card->set_guid("00000000-0000-0000-0000-000000000006");
    credit_cards->push_back(credit_card);
  }

  DISALLOW_COPY_AND_ASSIGN(TestPersonalDataManager);
};

// Populates |form| with data corresponding to a simple address form.
// Note that this actually appends fields to the form data, which can be useful
// for building up more complex test forms.
void CreateTestAddressFormData(FormData* form) {
  form->name = ASCIIToUTF16("MyForm");
  form->method = ASCIIToUTF16("POST");
  form->origin = GURL("http://myform.com/form.html");
  form->action = GURL("http://myform.com/submit.html");
  form->user_submitted = true;

  FormField field;
  autofill_test::CreateTestFormField(
      "First Name", "firstname", "", "text", &field);
  form->fields.push_back(field);
  autofill_test::CreateTestFormField(
      "Middle Name", "middlename", "", "text", &field);
  form->fields.push_back(field);
  autofill_test::CreateTestFormField(
      "Last Name", "lastname", "", "text", &field);
  form->fields.push_back(field);
  autofill_test::CreateTestFormField(
      "Address Line 1", "addr1", "", "text", &field);
  form->fields.push_back(field);
  autofill_test::CreateTestFormField(
      "Address Line 2", "addr2", "", "text", &field);
  form->fields.push_back(field);
  autofill_test::CreateTestFormField(
      "City", "city", "", "text", &field);
  form->fields.push_back(field);
  autofill_test::CreateTestFormField(
      "State", "state", "", "text", &field);
  form->fields.push_back(field);
  autofill_test::CreateTestFormField(
      "Postal Code", "zipcode", "", "text", &field);
  form->fields.push_back(field);
  autofill_test::CreateTestFormField(
      "Country", "country", "", "text", &field);
  form->fields.push_back(field);
  autofill_test::CreateTestFormField(
      "Phone Number", "phonenumber", "", "tel", &field);
  form->fields.push_back(field);
  autofill_test::CreateTestFormField(
      "Fax", "fax", "", "text", &field);
  form->fields.push_back(field);
  autofill_test::CreateTestFormField(
      "Email", "email", "", "email", &field);
  form->fields.push_back(field);
}

// Populates |form| with data corresponding to a simple credit card form.
// Note that this actually appends fields to the form data, which can be useful
// for building up more complex test forms.
void CreateTestCreditCardFormData(FormData* form,
                                  bool is_https,
                                  bool use_month_type) {
  form->name = ASCIIToUTF16("MyForm");
  form->method = ASCIIToUTF16("POST");
  if (is_https) {
    form->origin = GURL("https://myform.com/form.html");
    form->action = GURL("https://myform.com/submit.html");
  } else {
    form->origin = GURL("http://myform.com/form.html");
    form->action = GURL("http://myform.com/submit.html");
  }
  form->user_submitted = true;

  FormField field;
  autofill_test::CreateTestFormField(
      "Name on Card", "nameoncard", "", "text", &field);
  form->fields.push_back(field);
  autofill_test::CreateTestFormField(
      "Card Number", "cardnumber", "", "text", &field);
  form->fields.push_back(field);
  if (use_month_type) {
    autofill_test::CreateTestFormField(
        "Expiration Date", "ccmonth", "", "month", &field);
    form->fields.push_back(field);
  } else {
    autofill_test::CreateTestFormField(
        "Expiration Date", "ccmonth", "", "text", &field);
    form->fields.push_back(field);
    autofill_test::CreateTestFormField(
        "", "ccyear", "", "text", &field);
    form->fields.push_back(field);
  }
}

void ExpectSuggestions(int page_id,
                       const std::vector<string16>& values,
                       const std::vector<string16>& labels,
                       const std::vector<string16>& icons,
                       const std::vector<int>& unique_ids,
                       int expected_page_id,
                       size_t expected_num_suggestions,
                       const string16 expected_values[],
                       const string16 expected_labels[],
                       const string16 expected_icons[],
                       const int expected_unique_ids[]) {
  EXPECT_EQ(expected_page_id, page_id);
  ASSERT_EQ(expected_num_suggestions, values.size());
  ASSERT_EQ(expected_num_suggestions, labels.size());
  ASSERT_EQ(expected_num_suggestions, icons.size());
  ASSERT_EQ(expected_num_suggestions, unique_ids.size());
  for (size_t i = 0; i < expected_num_suggestions; ++i) {
    SCOPED_TRACE(StringPrintf("i: %" PRIuS, i));
    EXPECT_EQ(expected_values[i], values[i]);
    EXPECT_EQ(expected_labels[i], labels[i]);
    EXPECT_EQ(expected_icons[i], icons[i]);
    EXPECT_EQ(expected_unique_ids[i], unique_ids[i]);
  }
}

// Verifies that the |filled_form| has been filled with the given data.
// Verifies address fields if |has_address_fields| is true, and verifies
// credit card fields if |has_credit_card_fields| is true. Verifies both if both
// are true. |use_month_type| is used for credit card input month type.
void ExpectFilledForm(int page_id,
                      const FormData& filled_form,
                      int expected_page_id,
                      const char* first,
                      const char* middle,
                      const char* last,
                      const char* address1,
                      const char* address2,
                      const char* city,
                      const char* state,
                      const char* postal_code,
                      const char* country,
                      const char* phone,
                      const char* fax,
                      const char* email,
                      const char* name_on_card,
                      const char* card_number,
                      const char* expiration_month,
                      const char* expiration_year,
                      bool has_address_fields,
                      bool has_credit_card_fields,
                      bool use_month_type) {
  // The number of fields in the address and credit card forms created above.
  const size_t kAddressFormSize = 12;
  const size_t kCreditCardFormSize = use_month_type ? 3 : 4;

  EXPECT_EQ(expected_page_id, page_id);
  EXPECT_EQ(ASCIIToUTF16("MyForm"), filled_form.name);
  EXPECT_EQ(ASCIIToUTF16("POST"), filled_form.method);
  if (has_credit_card_fields) {
    EXPECT_EQ(GURL("https://myform.com/form.html"), filled_form.origin);
    EXPECT_EQ(GURL("https://myform.com/submit.html"), filled_form.action);
  } else {
    EXPECT_EQ(GURL("http://myform.com/form.html"), filled_form.origin);
    EXPECT_EQ(GURL("http://myform.com/submit.html"), filled_form.action);
  }
  EXPECT_TRUE(filled_form.user_submitted);

  size_t form_size = 0;
  if (has_address_fields)
    form_size += kAddressFormSize;
  if (has_credit_card_fields)
    form_size += kCreditCardFormSize;
  ASSERT_EQ(form_size, filled_form.fields.size());

  FormField field;
  if (has_address_fields) {
    autofill_test::CreateTestFormField(
        "First Name", "firstname", first, "text", &field);
    EXPECT_TRUE(field.StrictlyEqualsHack(filled_form.fields[0]));
    autofill_test::CreateTestFormField(
        "Middle Name", "middlename", middle, "text", &field);
    EXPECT_TRUE(field.StrictlyEqualsHack(filled_form.fields[1]));
    autofill_test::CreateTestFormField(
        "Last Name", "lastname", last, "text", &field);
    EXPECT_TRUE(field.StrictlyEqualsHack(filled_form.fields[2]));
    autofill_test::CreateTestFormField(
        "Address Line 1", "addr1", address1, "text", &field);
    EXPECT_TRUE(field.StrictlyEqualsHack(filled_form.fields[3]));
    autofill_test::CreateTestFormField(
        "Address Line 2", "addr2", address2, "text", &field);
    EXPECT_TRUE(field.StrictlyEqualsHack(filled_form.fields[4]));
    autofill_test::CreateTestFormField(
        "City", "city", city, "text", &field);
    EXPECT_TRUE(field.StrictlyEqualsHack(filled_form.fields[5]));
    autofill_test::CreateTestFormField(
        "State", "state", state, "text", &field);
    EXPECT_TRUE(field.StrictlyEqualsHack(filled_form.fields[6]));
    autofill_test::CreateTestFormField(
        "Postal Code", "zipcode", postal_code, "text", &field);
    EXPECT_TRUE(field.StrictlyEqualsHack(filled_form.fields[7]));
    autofill_test::CreateTestFormField(
        "Country", "country", country, "text", &field);
    EXPECT_TRUE(field.StrictlyEqualsHack(filled_form.fields[8]));
    autofill_test::CreateTestFormField(
        "Phone Number", "phonenumber", phone, "tel", &field);
    EXPECT_TRUE(field.StrictlyEqualsHack(filled_form.fields[9]));
    autofill_test::CreateTestFormField(
        "Fax", "fax", fax, "text", &field);
    EXPECT_TRUE(field.StrictlyEqualsHack(filled_form.fields[10]));
    autofill_test::CreateTestFormField(
        "Email", "email", email, "email", &field);
    EXPECT_TRUE(field.StrictlyEqualsHack(filled_form.fields[11]));
  }

  if (has_credit_card_fields) {
    size_t offset = has_address_fields? kAddressFormSize : 0;
    autofill_test::CreateTestFormField(
        "Name on Card", "nameoncard", name_on_card, "text", &field);
    EXPECT_TRUE(field.StrictlyEqualsHack(filled_form.fields[offset + 0]));
    autofill_test::CreateTestFormField(
        "Card Number", "cardnumber", card_number, "text", &field);
    EXPECT_TRUE(field.StrictlyEqualsHack(filled_form.fields[offset + 1]));
    if (use_month_type) {
      std::string exp_year = expiration_year;
      std::string exp_month = expiration_month;
      std::string date;
      if (!exp_year.empty() && !exp_month.empty())
        date = exp_year + "-" + exp_month;
      autofill_test::CreateTestFormField(
          "Expiration Date", "ccmonth", date.c_str(), "month", &field);
      EXPECT_TRUE(field.StrictlyEqualsHack(filled_form.fields[offset + 2]));
    } else {
      autofill_test::CreateTestFormField(
          "Expiration Date", "ccmonth", expiration_month, "text", &field);
      EXPECT_TRUE(field.StrictlyEqualsHack(filled_form.fields[offset + 2]));
      autofill_test::CreateTestFormField(
          "", "ccyear", expiration_year, "text", &field);
      EXPECT_TRUE(field.StrictlyEqualsHack(filled_form.fields[offset + 3]));
    }
  }
}

void ExpectFilledAddressFormElvis(int page_id,
                                  const FormData& filled_form,
                                  int expected_page_id,
                                  bool has_credit_card_fields) {
  ExpectFilledForm(page_id, filled_form, expected_page_id, "Elvis", "Aaron",
                   "Presley", "3734 Elvis Presley Blvd.", "Apt. 10", "Memphis",
                   "Tennessee", "38116", "United States", "12345678901", "",
                   "theking@gmail.com", "", "", "", "", true,
                   has_credit_card_fields, false);
}

void ExpectFilledCreditCardFormElvis(int page_id,
                                     const FormData& filled_form,
                                     int expected_page_id,
                                     bool has_address_fields) {
  ExpectFilledForm(page_id, filled_form, expected_page_id,
                   "", "", "", "", "", "", "", "", "", "", "", "",
                   "Elvis Presley", "4234567890123456", "04", "2012",
                   has_address_fields, true, false);
}

void ExpectFilledCreditCardYearMonthWithYearMonth(int page_id,
                                              const FormData& filled_form,
                                              int expected_page_id,
                                              bool has_address_fields,
                                              const char* year,
                                              const char* month) {
  ExpectFilledForm(page_id, filled_form, expected_page_id,
                   "", "", "", "", "", "", "", "", "", "", "", "",
                   "Miku Hatsune", "4234567890654321", month, year,
                   has_address_fields, true, true);
}

class TestAutofillManager : public AutofillManager {
 public:
  TestAutofillManager(TabContents* tab_contents,
                      TestPersonalDataManager* personal_manager)
      : AutofillManager(tab_contents, personal_manager),
        autofill_enabled_(true) {
    test_personal_data_ = personal_manager;
  }

  virtual bool IsAutofillEnabled() const { return autofill_enabled_; }

  void set_autofill_enabled(bool autofill_enabled) {
    autofill_enabled_ = autofill_enabled;
  }

  AutofillProfile* GetProfileWithGUID(const char* guid) {
    return test_personal_data_->GetProfileWithGUID(guid);
  }

  void AddProfile(AutofillProfile* profile) {
    test_personal_data_->AddProfile(profile);
  }

  void AddCreditCard(CreditCard* credit_card) {
    test_personal_data_->AddCreditCard(credit_card);
  }

  int GetPackedCreditCardID(int credit_card_id) {
    return PackGUIDs(IDToGUID(credit_card_id), GUIDPair(std::string(), 0));
  }

  virtual int GUIDToID(const GUIDPair& guid) OVERRIDE {
    if (guid.first.empty())
      return 0;

    int id;
    EXPECT_TRUE(base::StringToInt(guid.first.substr(guid.first.rfind("-") + 1),
                                  &id));
    return id;
  }

  virtual const GUIDPair IDToGUID(int id) OVERRIDE {
    EXPECT_TRUE(id >= 0);
    if (id <= 0)
      return GUIDPair(std::string(), 0);

    return GUIDPair(base::StringPrintf("00000000-0000-0000-0000-%012d", id), 0);
  }

  void AddSeenForm(FormStructure* form) {
    form_structures()->push_back(form);
  }

 private:
  TestPersonalDataManager* test_personal_data_;
  bool autofill_enabled_;

  DISALLOW_COPY_AND_ASSIGN(TestAutofillManager);
};

}  // namespace

class AutofillManagerTest : public TabContentsWrapperTestHarness {
 public:
  typedef AutofillManager::GUIDPair GUIDPair;

  AutofillManagerTest() {}
  virtual ~AutofillManagerTest() {
    // Order of destruction is important as AutofillManager relies on
    // PersonalDataManager to be around when it gets destroyed.
    autofill_manager_.reset(NULL);
    test_personal_data_ = NULL;
  }

  virtual void SetUp() {
    TabContentsWrapperTestHarness::SetUp();
    test_personal_data_ = new TestPersonalDataManager();
    autofill_manager_.reset(new TestAutofillManager(contents(),
                                                    test_personal_data_.get()));
  }

  Profile* profile() { return contents()->profile(); }

  void GetAutofillSuggestions(int query_id,
                              const webkit_glue::FormData& form,
                              const webkit_glue::FormField& field) {
    autofill_manager_->OnQueryFormFieldAutofill(query_id, form, field);
  }

  void GetAutofillSuggestions(const webkit_glue::FormData& form,
                              const webkit_glue::FormField& field) {
    GetAutofillSuggestions(kDefaultPageID, form, field);
  }

  void AutocompleteSuggestionsReturned(const std::vector<string16>& result) {
    contents_wrapper()->autocomplete_history_manager()->
        SendSuggestions(&result);
  }

  void FormsSeen(const std::vector<webkit_glue::FormData>& forms) {
    autofill_manager_->OnFormsSeen(forms);
  }

  void FormSubmitted(const FormData& form) {
    autofill_manager_->OnFormSubmitted(form);
  }

  void FillAutofillFormData(int query_id,
                            const webkit_glue::FormData& form,
                            const webkit_glue::FormField& field,
                            int unique_id) {
    autofill_manager_->OnFillAutofillFormData(query_id, form, field, unique_id);
  }

  bool GetAutofillSuggestionsMessage(int* page_id,
                                     std::vector<string16>* values,
                                     std::vector<string16>* labels,
                                     std::vector<string16>* icons,
                                     std::vector<int>* unique_ids) {
    const uint32 kMsgID = AutofillMsg_SuggestionsReturned::ID;
    const IPC::Message* message =
        process()->sink().GetFirstMessageMatching(kMsgID);
    if (!message)
      return false;

    AutofillParam autofill_param;
    AutofillMsg_SuggestionsReturned::Read(message, &autofill_param);
    if (page_id)
      *page_id = autofill_param.a;
    if (values)
      *values = autofill_param.b;
    if (labels)
      *labels = autofill_param.c;
    if (icons)
      *icons = autofill_param.d;
    if (unique_ids)
      *unique_ids = autofill_param.e;

    contents_wrapper()->autocomplete_history_manager()->CancelPendingQuery();
    process()->sink().ClearMessages();
    return true;
  }

  bool GetAutofillFormDataFilledMessage(int *page_id, FormData* results) {
    const uint32 kMsgID = AutofillMsg_FormDataFilled::ID;
    const IPC::Message* message =
        process()->sink().GetFirstMessageMatching(kMsgID);
    if (!message)
      return false;
    Tuple2<int, FormData> autofill_param;
    AutofillMsg_FormDataFilled::Read(message, &autofill_param);
    if (page_id)
      *page_id = autofill_param.a;
    if (results)
      *results = autofill_param.b;

    process()->sink().ClearMessages();
    return true;
  }

 protected:
  scoped_ptr<TestAutofillManager> autofill_manager_;
  scoped_refptr<TestPersonalDataManager> test_personal_data_;

 private:
  DISALLOW_COPY_AND_ASSIGN(AutofillManagerTest);
};

class TestFormStructure : public FormStructure {
 public:
  explicit TestFormStructure(const FormData& form) : FormStructure(form) {}
  virtual ~TestFormStructure() {}

  void SetFieldTypes(const std::vector<AutofillFieldType>& heuristic_types,
                     const std::vector<AutofillFieldType>& server_types) {
    ASSERT_EQ(field_count(), heuristic_types.size());
    ASSERT_EQ(field_count(), server_types.size());

    for (size_t i = 0; i < field_count(); ++i) {
      AutofillField* field = (*fields())[i];
      ASSERT_TRUE(field);
      field->set_heuristic_type(heuristic_types[i]);
      field->set_server_type(server_types[i]);
    }

    UpdateAutofillCount();
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(TestFormStructure);
};

// Test that we return all address profile suggestions when all form fields are
// empty.
TEST_F(AutofillManagerTest, GetProfileSuggestionsEmptyValue) {
  // Set up our form data.
  FormData form;
  CreateTestAddressFormData(&form);
  std::vector<FormData> forms(1, form);
  FormsSeen(forms);

  const FormField& field = form.fields[0];
  GetAutofillSuggestions(form, field);

  // No suggestions provided, so send an empty vector as the results.
  // This triggers the combined message send.
  AutocompleteSuggestionsReturned(std::vector<string16>());

  // Test that we sent the right message to the renderer.
  int page_id = 0;
  std::vector<string16> values;
  std::vector<string16> labels;
  std::vector<string16> icons;
  std::vector<int> unique_ids;
  GetAutofillSuggestionsMessage(
      &page_id, &values, &labels, &icons, &unique_ids);

  string16 expected_values[] = {
    ASCIIToUTF16("Elvis"),
    ASCIIToUTF16("Charles")
  };
  // Inferred labels include full first relevant field, which in this case is
  // the address line 1.
  string16 expected_labels[] = {
    ASCIIToUTF16("3734 Elvis Presley Blvd."),
    ASCIIToUTF16("123 Apple St.")
  };
  string16 expected_icons[] = {string16(), string16()};
  int expected_unique_ids[] = {1, 2};
  ExpectSuggestions(page_id, values, labels, icons, unique_ids,
                    kDefaultPageID, arraysize(expected_values), expected_values,
                    expected_labels, expected_icons, expected_unique_ids);
}

// Test that we return only matching address profile suggestions when the
// selected form field has been partially filled out.
TEST_F(AutofillManagerTest, GetProfileSuggestionsMatchCharacter) {
  // Set up our form data.
  FormData form;
  CreateTestAddressFormData(&form);
  std::vector<FormData> forms(1, form);
  FormsSeen(forms);

  FormField field;
  autofill_test::CreateTestFormField("First Name", "firstname", "E", "text",
                                     &field);
  GetAutofillSuggestions(form, field);

  // No suggestions provided, so send an empty vector as the results.
  // This triggers the combined message send.
  AutocompleteSuggestionsReturned(std::vector<string16>());

  // Test that we sent the right message to the renderer.
  int page_id = 0;
  std::vector<string16> values;
  std::vector<string16> labels;
  std::vector<string16> icons;
  std::vector<int> unique_ids;
  EXPECT_TRUE(GetAutofillSuggestionsMessage(&page_id, &values, &labels, &icons,
                                            &unique_ids));

  string16 expected_values[] = {ASCIIToUTF16("Elvis")};
  string16 expected_labels[] = {ASCIIToUTF16("3734 Elvis Presley Blvd.")};
  string16 expected_icons[] = {string16()};
  int expected_unique_ids[] = {1};
  ExpectSuggestions(page_id, values, labels, icons, unique_ids,
                    kDefaultPageID, arraysize(expected_values), expected_values,
                    expected_labels, expected_icons, expected_unique_ids);
}

// Test that we return no suggestions when the form has no relevant fields.
TEST_F(AutofillManagerTest, GetProfileSuggestionsUnknownFields) {
  // Set up our form data.
  FormData form;
  form.name = ASCIIToUTF16("MyForm");
  form.method = ASCIIToUTF16("POST");
  form.origin = GURL("http://myform.com/form.html");
  form.action = GURL("http://myform.com/submit.html");
  form.user_submitted = true;

  FormField field;
  autofill_test::CreateTestFormField("Username", "username", "", "text",
                                     &field);
  form.fields.push_back(field);
  autofill_test::CreateTestFormField("Password", "password", "", "password",
                                     &field);
  form.fields.push_back(field);
  autofill_test::CreateTestFormField("Quest", "quest", "", "quest", &field);
  form.fields.push_back(field);
  autofill_test::CreateTestFormField("Color", "color", "", "text", &field);
  form.fields.push_back(field);

  std::vector<FormData> forms(1, form);
  FormsSeen(forms);

  GetAutofillSuggestions(form, field);
  EXPECT_FALSE(GetAutofillSuggestionsMessage(NULL, NULL, NULL, NULL, NULL));
}

// Test that we cull duplicate profile suggestions.
TEST_F(AutofillManagerTest, GetProfileSuggestionsWithDuplicates) {
  // Set up our form data.
  FormData form;
  CreateTestAddressFormData(&form);
  std::vector<FormData> forms(1, form);
  FormsSeen(forms);

  // Add a duplicate profile.
  AutofillProfile* duplicate_profile =
      new AutofillProfile(
          *(autofill_manager_->GetProfileWithGUID(
              "00000000-0000-0000-0000-000000000001")));
  autofill_manager_->AddProfile(duplicate_profile);

  const FormField& field = form.fields[0];
  GetAutofillSuggestions(form, field);

  // No suggestions provided, so send an empty vector as the results.
  // This triggers the combined message send.
  AutocompleteSuggestionsReturned(std::vector<string16>());

  // Test that we sent the right message to the renderer.
  int page_id = 0;
  std::vector<string16> values;
  std::vector<string16> labels;
  std::vector<string16> icons;
  std::vector<int> unique_ids;
  EXPECT_TRUE(GetAutofillSuggestionsMessage(&page_id, &values, &labels, &icons,
                                            &unique_ids));

  string16 expected_values[] = {
    ASCIIToUTF16("Elvis"),
    ASCIIToUTF16("Charles")
  };
  string16 expected_labels[] = {
    ASCIIToUTF16("3734 Elvis Presley Blvd."),
    ASCIIToUTF16("123 Apple St.")
  };
  string16 expected_icons[] = {string16(), string16()};
  int expected_unique_ids[] = {1, 2};
  ExpectSuggestions(page_id, values, labels, icons, unique_ids,
                    kDefaultPageID, arraysize(expected_values), expected_values,
                    expected_labels, expected_icons, expected_unique_ids);
}

// Test that we return no suggestions when autofill is disabled.
TEST_F(AutofillManagerTest, GetProfileSuggestionsAutofillDisabledByUser) {
  // Set up our form data.
  FormData form;
  CreateTestAddressFormData(&form);
  std::vector<FormData> forms(1, form);
  FormsSeen(forms);

  // Disable Autofill.
  autofill_manager_->set_autofill_enabled(false);

  const FormField& field = form.fields[0];
  GetAutofillSuggestions(form, field);
  EXPECT_FALSE(GetAutofillSuggestionsMessage(NULL, NULL, NULL, NULL, NULL));
}

// Test that we return a warning explaining that autofill suggestions are
// unavailable when the form method is GET rather than POST.
TEST_F(AutofillManagerTest, GetProfileSuggestionsMethodGet) {
  // Set up our form data.
  FormData form;
  CreateTestAddressFormData(&form);
  form.method = ASCIIToUTF16("GET");
  std::vector<FormData> forms(1, form);
  FormsSeen(forms);

  const FormField& field = form.fields[0];
  GetAutofillSuggestions(form, field);

  // No suggestions provided, so send an empty vector as the results.
  // This triggers the combined message send.
  AutocompleteSuggestionsReturned(std::vector<string16>());

  // Test that we sent the right message to the renderer.
  int page_id = 0;
  std::vector<string16> values;
  std::vector<string16> labels;
  std::vector<string16> icons;
  std::vector<int> unique_ids;
  EXPECT_TRUE(GetAutofillSuggestionsMessage(&page_id, &values, &labels, &icons,
                                            &unique_ids));

  string16 expected_values[] = {
    l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_FORM_DISABLED)
  };
  string16 expected_labels[] = {string16()};
  string16 expected_icons[] = {string16()};
  int expected_unique_ids[] = {-1};
  ExpectSuggestions(page_id, values, labels, icons, unique_ids,
                    kDefaultPageID, arraysize(expected_values), expected_values,
                    expected_labels, expected_icons, expected_unique_ids);

  // Now add some Autocomplete suggestions. We should return the autocomplete
  // suggestions and the warning; these will be culled by the renderer.
  const int kPageID2 = 2;
  GetAutofillSuggestions(kPageID2, form, field);

  std::vector<string16> suggestions;
  suggestions.push_back(ASCIIToUTF16("Jay"));
  suggestions.push_back(ASCIIToUTF16("Jason"));
  AutocompleteSuggestionsReturned(suggestions);

  EXPECT_TRUE(GetAutofillSuggestionsMessage(&page_id, &values, &labels, &icons,
                                            &unique_ids));

  string16 expected_values2[] = {
    l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_FORM_DISABLED),
    ASCIIToUTF16("Jay"),
    ASCIIToUTF16("Jason")
  };
  string16 expected_labels2[] = {string16(), string16(), string16()};
  string16 expected_icons2[] = {string16(), string16(), string16()};
  int expected_unique_ids2[] = {-1, 0, 0};
  ExpectSuggestions(page_id, values, labels, icons, unique_ids,
                    kPageID2, arraysize(expected_values2), expected_values2,
                    expected_labels2, expected_icons2, expected_unique_ids2);

  // Now clear the test profiles and try again -- we shouldn't return a warning.
  test_personal_data_->ClearAutofillProfiles();
  GetAutofillSuggestions(form, field);
  EXPECT_FALSE(GetAutofillSuggestionsMessage(NULL, NULL, NULL, NULL, NULL));
}

// Test that we return all credit card profile suggestions when all form fields
// are empty.
TEST_F(AutofillManagerTest, GetCreditCardSuggestionsEmptyValue) {
  // Set up our form data.
  FormData form;
  CreateTestCreditCardFormData(&form, true, false);
  std::vector<FormData> forms(1, form);
  FormsSeen(forms);

  FormField field = form.fields[1];
  GetAutofillSuggestions(form, field);

  // No suggestions provided, so send an empty vector as the results.
  // This triggers the combined message send.
  AutocompleteSuggestionsReturned(std::vector<string16>());

  // Test that we sent the right message to the renderer.
  int page_id = 0;
  std::vector<string16> values;
  std::vector<string16> labels;
  std::vector<string16> icons;
  std::vector<int> unique_ids;
  EXPECT_TRUE(GetAutofillSuggestionsMessage(&page_id, &values, &labels, &icons,
                                            &unique_ids));

  string16 expected_values[] = {
    ASCIIToUTF16("************3456"),
    ASCIIToUTF16("************8765")
  };
  string16 expected_labels[] = {ASCIIToUTF16("*3456"), ASCIIToUTF16("*8765")};
  string16 expected_icons[] = {
    ASCIIToUTF16("visaCC"),
    ASCIIToUTF16("genericCC")
  };
  int expected_unique_ids[] = {
    autofill_manager_->GetPackedCreditCardID(4),
    autofill_manager_->GetPackedCreditCardID(5)
  };
  ExpectSuggestions(page_id, values, labels, icons, unique_ids,
                    kDefaultPageID, arraysize(expected_values), expected_values,
                    expected_labels, expected_icons, expected_unique_ids);
}

// Test that we return only matching credit card profile suggestions when the
// selected form field has been partially filled out.
TEST_F(AutofillManagerTest, GetCreditCardSuggestionsMatchCharacter) {
  // Set up our form data.
  FormData form;
  CreateTestCreditCardFormData(&form, true, false);
  std::vector<FormData> forms(1, form);
  FormsSeen(forms);

  FormField field;
  autofill_test::CreateTestFormField(
      "Card Number", "cardnumber", "4", "text", &field);
  GetAutofillSuggestions(form, field);

  // No suggestions provided, so send an empty vector as the results.
  // This triggers the combined message send.
  AutocompleteSuggestionsReturned(std::vector<string16>());

  // Test that we sent the right message to the renderer.
  int page_id = 0;
  std::vector<string16> values;
  std::vector<string16> labels;
  std::vector<string16> icons;
  std::vector<int> unique_ids;
  EXPECT_TRUE(GetAutofillSuggestionsMessage(&page_id, &values, &labels, &icons,
                                            &unique_ids));

  string16 expected_values[] = {ASCIIToUTF16("************3456")};
  string16 expected_labels[] = {ASCIIToUTF16("*3456")};
  string16 expected_icons[] = {ASCIIToUTF16("visaCC")};
  int expected_unique_ids[] = {autofill_manager_->GetPackedCreditCardID(4)};
  ExpectSuggestions(page_id, values, labels, icons, unique_ids,
                    kDefaultPageID, arraysize(expected_values), expected_values,
                    expected_labels, expected_icons, expected_unique_ids);
}

// Test that we return credit card profile suggestions when the selected form
// field is not the credit card number field.
TEST_F(AutofillManagerTest, GetCreditCardSuggestionsNonCCNumber) {
  // Set up our form data.
  FormData form;
  CreateTestCreditCardFormData(&form, true, false);
  std::vector<FormData> forms(1, form);
  FormsSeen(forms);

  const FormField& field = form.fields[0];
  GetAutofillSuggestions(form, field);

  // No suggestions provided, so send an empty vector as the results.
  // This triggers the combined message send.
  AutocompleteSuggestionsReturned(std::vector<string16>());

  // Test that we sent the right message to the renderer.
  int page_id = 0;
  std::vector<string16> values;
  std::vector<string16> labels;
  std::vector<string16> icons;
  std::vector<int> unique_ids;
  EXPECT_TRUE(GetAutofillSuggestionsMessage(&page_id, &values, &labels, &icons,
                                            &unique_ids));

  string16 expected_values[] = {
    ASCIIToUTF16("Elvis Presley"),
    ASCIIToUTF16("Buddy Holly")
  };
  string16 expected_labels[] = {ASCIIToUTF16("*3456"), ASCIIToUTF16("*8765")};
  string16 expected_icons[] = {
    ASCIIToUTF16("visaCC"),
    ASCIIToUTF16("genericCC")
  };
  int expected_unique_ids[] = {
    autofill_manager_->GetPackedCreditCardID(4),
    autofill_manager_->GetPackedCreditCardID(5)
  };
  ExpectSuggestions(page_id, values, labels, icons, unique_ids,
                    kDefaultPageID, arraysize(expected_values), expected_values,
                    expected_labels, expected_icons, expected_unique_ids);
}

// Test that we return a warning explaining that credit card profile suggestions
// are unavailable when the form is not https.
TEST_F(AutofillManagerTest, GetCreditCardSuggestionsNonHTTPS) {
  // Set up our form data.
  FormData form;
  CreateTestCreditCardFormData(&form, false, false);
  std::vector<FormData> forms(1, form);
  FormsSeen(forms);

  const FormField& field = form.fields[0];
  GetAutofillSuggestions(form, field);

  // No suggestions provided, so send an empty vector as the results.
  // This triggers the combined message send.
  AutocompleteSuggestionsReturned(std::vector<string16>());

  // Test that we sent the right message to the renderer.
  int page_id = 0;
  std::vector<string16> values;
  std::vector<string16> labels;
  std::vector<string16> icons;
  std::vector<int> unique_ids;
  EXPECT_TRUE(GetAutofillSuggestionsMessage(&page_id, &values, &labels, &icons,
                                            &unique_ids));

  string16 expected_values[] = {
    l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_INSECURE_CONNECTION)
  };
  string16 expected_labels[] = {string16()};
  string16 expected_icons[] = {string16()};
  int expected_unique_ids[] = {-1};
  ExpectSuggestions(page_id, values, labels, icons, unique_ids,
                    kDefaultPageID, arraysize(expected_values), expected_values,
                    expected_labels, expected_icons, expected_unique_ids);

  // Now add some Autocomplete suggestions. We should show the autocomplete
  // suggestions and the warning.
  const int kPageID2 = 2;
  GetAutofillSuggestions(kPageID2, form, field);

  std::vector<string16> suggestions;
  suggestions.push_back(ASCIIToUTF16("Jay"));
  suggestions.push_back(ASCIIToUTF16("Jason"));
  AutocompleteSuggestionsReturned(suggestions);

  EXPECT_TRUE(GetAutofillSuggestionsMessage(&page_id, &values, &labels, &icons,
                                            &unique_ids));
  string16 expected_values2[] = {
    l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_INSECURE_CONNECTION),
    ASCIIToUTF16("Jay"),
    ASCIIToUTF16("Jason")
  };
  string16 expected_labels2[] = {string16(), string16(), string16()};
  string16 expected_icons2[] = {string16(), string16(), string16()};
  int expected_unique_ids2[] = {-1, 0, 0};
  ExpectSuggestions(page_id, values, labels, icons, unique_ids,
                    kPageID2, arraysize(expected_values2), expected_values2,
                    expected_labels2, expected_icons2, expected_unique_ids2);

  // Clear the test credit cards and try again -- we shouldn't return a warning.
  test_personal_data_->ClearCreditCards();
  GetAutofillSuggestions(form, field);
  EXPECT_FALSE(GetAutofillSuggestionsMessage(NULL, NULL, NULL, NULL, NULL));
}

// Test that we return all credit card suggestions in the case that two cards
// have the same obfuscated number.
TEST_F(AutofillManagerTest, GetCreditCardSuggestionsRepeatedObfuscatedNumber) {
  // Add a credit card with the same obfuscated number as Elvis's.
  // |credit_card| will be owned by the mock PersonalDataManager.
  CreditCard* credit_card = new CreditCard;
  autofill_test::SetCreditCardInfo(credit_card, "Elvis Presley",
                                   "5231567890123456",  // Mastercard
                                   "04", "2012");
  credit_card->set_guid("00000000-0000-0000-0000-000000000007");
  autofill_manager_->AddCreditCard(credit_card);

  // Set up our form data.
  FormData form;
  CreateTestCreditCardFormData(&form, true, false);
  std::vector<FormData> forms(1, form);
  FormsSeen(forms);

  FormField field = form.fields[1];
  GetAutofillSuggestions(form, field);

  // No suggestions provided, so send an empty vector as the results.
  // This triggers the combined message send.
  AutocompleteSuggestionsReturned(std::vector<string16>());

  // Test that we sent the right message to the renderer.
  int page_id = 0;
  std::vector<string16> values;
  std::vector<string16> labels;
  std::vector<string16> icons;
  std::vector<int> unique_ids;
  EXPECT_TRUE(GetAutofillSuggestionsMessage(&page_id, &values, &labels, &icons,
                                            &unique_ids));

  string16 expected_values[] = {
    ASCIIToUTF16("************3456"),
    ASCIIToUTF16("************8765"),
    ASCIIToUTF16("************3456")
  };
  string16 expected_labels[] = {
    ASCIIToUTF16("*3456"),
    ASCIIToUTF16("*8765"),
    ASCIIToUTF16("*3456"),
  };
  string16 expected_icons[] = {
    ASCIIToUTF16("visaCC"),
    ASCIIToUTF16("genericCC"),
    ASCIIToUTF16("masterCardCC")
  };
  int expected_unique_ids[] = {
    autofill_manager_->GetPackedCreditCardID(4),
    autofill_manager_->GetPackedCreditCardID(5),
    autofill_manager_->GetPackedCreditCardID(7)
  };
  ExpectSuggestions(page_id, values, labels, icons, unique_ids,
                    kDefaultPageID, arraysize(expected_values), expected_values,
                    expected_labels, expected_icons, expected_unique_ids);
}

// Test that we return profile and credit card suggestions for combined forms.
TEST_F(AutofillManagerTest, GetAddressAndCreditCardSuggestions) {
  // Set up our form data.
  FormData form;
  CreateTestAddressFormData(&form);
  CreateTestCreditCardFormData(&form, true, false);
  std::vector<FormData> forms(1, form);
  FormsSeen(forms);

  FormField field = form.fields[0];
  GetAutofillSuggestions(form, field);

  // No suggestions provided, so send an empty vector as the results.
  // This triggers the combined message send.
  AutocompleteSuggestionsReturned(std::vector<string16>());

  // Test that we sent the right address suggestions to the renderer.
  int page_id = 0;
  std::vector<string16> values;
  std::vector<string16> labels;
  std::vector<string16> icons;
  std::vector<int> unique_ids;
  EXPECT_TRUE(GetAutofillSuggestionsMessage(&page_id, &values, &labels, &icons,
                                            &unique_ids));

  string16 expected_values[] = {
    ASCIIToUTF16("Elvis"),
    ASCIIToUTF16("Charles")
  };
  string16 expected_labels[] = {
    ASCIIToUTF16("3734 Elvis Presley Blvd."),
    ASCIIToUTF16("123 Apple St.")
  };
  string16 expected_icons[] = {string16(), string16()};
  int expected_unique_ids[] = {1, 2};
  ExpectSuggestions(page_id, values, labels, icons, unique_ids,
                    kDefaultPageID, arraysize(expected_values), expected_values,
                    expected_labels, expected_icons, expected_unique_ids);

  const int kPageID2 = 2;
  autofill_test::CreateTestFormField(
      "Card Number", "cardnumber", "", "text", &field);
  GetAutofillSuggestions(kPageID2, form, field);

  // No suggestions provided, so send an empty vector as the results.
  // This triggers the combined message send.
  AutocompleteSuggestionsReturned(std::vector<string16>());

  // Test that we sent the credit card suggestions to the renderer.
  page_id = 0;
  EXPECT_TRUE(GetAutofillSuggestionsMessage(&page_id, &values, &labels, &icons,
                                            &unique_ids));

  string16 expected_values2[] = {
    ASCIIToUTF16("************3456"),
    ASCIIToUTF16("************8765")
  };
  string16 expected_labels2[] = {ASCIIToUTF16("*3456"), ASCIIToUTF16("*8765")};
  string16 expected_icons2[] = {
    ASCIIToUTF16("visaCC"),
    ASCIIToUTF16("genericCC")
  };
  int expected_unique_ids2[] = {
    autofill_manager_->GetPackedCreditCardID(4),
    autofill_manager_->GetPackedCreditCardID(5)
  };
  ExpectSuggestions(page_id, values, labels, icons, unique_ids,
                    kPageID2, arraysize(expected_values2), expected_values2,
                    expected_labels2, expected_icons2, expected_unique_ids2);
}

// Test that for non-https forms with both address and credit card fields, we
// only return address suggestions. Instead of credit card suggestions, we
// should return a warning explaining that credit card profile suggestions are
// unavailable when the form is not https.
TEST_F(AutofillManagerTest, GetAddressAndCreditCardSuggestionsNonHttps) {
  // Set up our form data.
  FormData form;
  CreateTestAddressFormData(&form);
  CreateTestCreditCardFormData(&form, false, false);
  std::vector<FormData> forms(1, form);
  FormsSeen(forms);

  FormField field = form.fields[0];
  GetAutofillSuggestions(form, field);

  // No suggestions provided, so send an empty vector as the results.
  // This triggers the combined message send.
  AutocompleteSuggestionsReturned(std::vector<string16>());

  // Test that we sent the right address suggestions to the renderer.
  int page_id = 0;
  std::vector<string16> values;
  std::vector<string16> labels;
  std::vector<string16> icons;
  std::vector<int> unique_ids;
  EXPECT_TRUE(GetAutofillSuggestionsMessage(&page_id, &values, &labels, &icons,
                                            &unique_ids));

  string16 expected_values[] = {
    ASCIIToUTF16("Elvis"),
    ASCIIToUTF16("Charles")
  };
  string16 expected_labels[] = {
    ASCIIToUTF16("3734 Elvis Presley Blvd."),
    ASCIIToUTF16("123 Apple St.")
  };
  string16 expected_icons[] = {string16(), string16()};
  int expected_unique_ids[] = {1, 2};
  ExpectSuggestions(page_id, values, labels, icons, unique_ids,
                    kDefaultPageID, arraysize(expected_values), expected_values,
                    expected_labels, expected_icons, expected_unique_ids);

  autofill_test::CreateTestFormField(
      "Card Number", "cardnumber", "", "text", &field);
  const int kPageID2 = 2;
  GetAutofillSuggestions(kPageID2, form, field);

  // No suggestions provided, so send an empty vector as the results.
  // This triggers the combined message send.
  AutocompleteSuggestionsReturned(std::vector<string16>());

  // Test that we sent the right message to the renderer.
  EXPECT_TRUE(GetAutofillSuggestionsMessage(&page_id, &values, &labels, &icons,
                                            &unique_ids));

  string16 expected_values2[] = {
    l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_INSECURE_CONNECTION)
  };
  string16 expected_labels2[] = {string16()};
  string16 expected_icons2[] = {string16()};
  int expected_unique_ids2[] = {-1};
  ExpectSuggestions(page_id, values, labels, icons, unique_ids,
                    kPageID2, arraysize(expected_values2), expected_values2,
                    expected_labels2, expected_icons2, expected_unique_ids2);

  // Clear the test credit cards and try again -- we shouldn't return a warning.
  test_personal_data_->ClearCreditCards();
  GetAutofillSuggestions(form, field);
  EXPECT_FALSE(GetAutofillSuggestionsMessage(NULL, NULL, NULL, NULL, NULL));
}

// Test that we correctly combine autofill and autocomplete suggestions.
TEST_F(AutofillManagerTest, GetCombinedAutofillAndAutocompleteSuggestions) {
  // Set up our form data.
  FormData form;
  CreateTestAddressFormData(&form);
  std::vector<FormData> forms(1, form);
  FormsSeen(forms);

  const FormField& field = form.fields[0];
  GetAutofillSuggestions(form, field);

  // Add some Autocomplete suggestions.
  // This triggers the combined message send.
  std::vector<string16> suggestions;
  suggestions.push_back(ASCIIToUTF16("Jay"));
  // This suggestion is a duplicate, and should be trimmed.
  suggestions.push_back(ASCIIToUTF16("Elvis"));
  suggestions.push_back(ASCIIToUTF16("Jason"));
  AutocompleteSuggestionsReturned(suggestions);

  // Test that we sent the right message to the renderer.
  int page_id = 0;
  std::vector<string16> values;
  std::vector<string16> labels;
  std::vector<string16> icons;
  std::vector<int> unique_ids;
  EXPECT_TRUE(GetAutofillSuggestionsMessage(&page_id, &values, &labels, &icons,
                                            &unique_ids));

  string16 expected_values[] = {
    ASCIIToUTF16("Elvis"),
    ASCIIToUTF16("Charles"),
    ASCIIToUTF16("Jay"),
    ASCIIToUTF16("Jason")
  };
  string16 expected_labels[] = {
    ASCIIToUTF16("3734 Elvis Presley Blvd."),
    ASCIIToUTF16("123 Apple St."),
    string16(),
    string16()
  };
  string16 expected_icons[] = {string16(), string16(), string16(), string16()};
  int expected_unique_ids[] = {1, 2, 0, 0};
  ExpectSuggestions(page_id, values, labels, icons, unique_ids,
                    kDefaultPageID, arraysize(expected_values), expected_values,
                    expected_labels, expected_icons, expected_unique_ids);
}

// Test that we return autocomplete-like suggestions when trying to autofill
// already filled forms.
TEST_F(AutofillManagerTest, GetFieldSuggestionsWhenFormIsAutofilled) {
  // Set up our form data.
  FormData form;
  CreateTestAddressFormData(&form);
  std::vector<FormData> forms(1, form);
  FormsSeen(forms);

  // Mark one of the fields as filled.
  form.fields[2].is_autofilled = true;
  const FormField& field = form.fields[0];
  GetAutofillSuggestions(form, field);

  // No suggestions provided, so send an empty vector as the results.
  // This triggers the combined message send.
  AutocompleteSuggestionsReturned(std::vector<string16>());

  // Test that we sent the right message to the renderer.
  int page_id = 0;
  std::vector<string16> values;
  std::vector<string16> labels;
  std::vector<string16> icons;
  std::vector<int> unique_ids;
  EXPECT_TRUE(GetAutofillSuggestionsMessage(&page_id, &values, &labels, &icons,
                                            &unique_ids));
  string16 expected_values[] = {
    ASCIIToUTF16("Elvis"),
    ASCIIToUTF16("Charles")
  };
  string16 expected_labels[] = {string16(), string16()};
  string16 expected_icons[] = {string16(), string16()};
  int expected_unique_ids[] = {1, 2};
  ExpectSuggestions(page_id, values, labels, icons, unique_ids,
                    kDefaultPageID, arraysize(expected_values), expected_values,
                    expected_labels, expected_icons, expected_unique_ids);
}

// Test that nothing breaks when there are autocomplete suggestions but no
// autofill suggestions.
TEST_F(AutofillManagerTest, GetFieldSuggestionsForAutocompleteOnly) {
  // Set up our form data.
  FormData form;
  CreateTestAddressFormData(&form);
  FormField field;
  autofill_test::CreateTestFormField(
      "Some Field", "somefield", "", "text", &field);
  form.fields.push_back(field);
  std::vector<FormData> forms(1, form);
  FormsSeen(forms);

  GetAutofillSuggestions(form, field);

  // Add some Autocomplete suggestions.
  // This triggers the combined message send.
  std::vector<string16> suggestions;
  suggestions.push_back(ASCIIToUTF16("one"));
  suggestions.push_back(ASCIIToUTF16("two"));
  AutocompleteSuggestionsReturned(suggestions);

  // Test that we sent the right message to the renderer.
  int page_id = 0;
  std::vector<string16> values;
  std::vector<string16> labels;
  std::vector<string16> icons;
  std::vector<int> unique_ids;
  EXPECT_TRUE(GetAutofillSuggestionsMessage(&page_id, &values, &labels, &icons,
                                            &unique_ids));

  string16 expected_values[] = {
    ASCIIToUTF16("one"),
    ASCIIToUTF16("two")
  };
  string16 expected_labels[] = {string16(), string16()};
  string16 expected_icons[] = {string16(), string16()};
  int expected_unique_ids[] = {0, 0};
  ExpectSuggestions(page_id, values, labels, icons, unique_ids,
                    kDefaultPageID, arraysize(expected_values), expected_values,
                    expected_labels, expected_icons, expected_unique_ids);
}

// Test that we do not return duplicate values drawn from multiple profiles when
// filling an already filled field.
TEST_F(AutofillManagerTest, GetFieldSuggestionsWithDuplicateValues) {
  // Set up our form data.
  FormData form;
  CreateTestAddressFormData(&form);
  std::vector<FormData> forms(1, form);
  FormsSeen(forms);

  // |profile| will be owned by the mock PersonalDataManager.
  AutofillProfile* profile = new AutofillProfile;
  autofill_test::SetProfileInfo(profile, "Elvis", "", "", "", "",
                                "", "", "", "", "", "", "", "");
  profile->set_guid("00000000-0000-0000-0000-000000000101");
  autofill_manager_->AddProfile(profile);

  FormField& field = form.fields[0];
  field.is_autofilled = true;
  field.value = ASCIIToUTF16("Elvis");
  GetAutofillSuggestions(form, field);

  // No suggestions provided, so send an empty vector as the results.
  // This triggers the combined message send.
  AutocompleteSuggestionsReturned(std::vector<string16>());

  // Test that we sent the right message to the renderer.
  int page_id = 0;
  std::vector<string16> values;
  std::vector<string16> labels;
  std::vector<string16> icons;
  std::vector<int> unique_ids;
  EXPECT_TRUE(GetAutofillSuggestionsMessage(&page_id, &values, &labels, &icons,
                                            &unique_ids));

  string16 expected_values[] = { ASCIIToUTF16("Elvis") };
  string16 expected_labels[] = { string16() };
  string16 expected_icons[] = { string16() };
  int expected_unique_ids[] = { 1 };
  ExpectSuggestions(page_id, values, labels, icons, unique_ids,
                    kDefaultPageID, arraysize(expected_values), expected_values,
                    expected_labels, expected_icons, expected_unique_ids);
}

// Test that a non-default value is suggested for multi-valued profile, on an
// unfilled form.
TEST_F(AutofillManagerTest, GetFieldSuggestionsForMultiValuedProfileUnfilled) {
  // Set up our form data.
  FormData form;
  CreateTestAddressFormData(&form);
  std::vector<FormData> forms(1, form);
  FormsSeen(forms);

  // |profile| will be owned by the mock PersonalDataManager.
  AutofillProfile* profile = new AutofillProfile;
  autofill_test::SetProfileInfo(profile, "Elvis", "", "Presley", "me@x.com", "",
                                "", "", "", "", "", "", "", "");
  profile->set_guid("00000000-0000-0000-0000-000000000101");
  std::vector<string16> multi_values(2);
  multi_values[0] = ASCIIToUTF16("Elvis Presley");
  multi_values[1] = ASCIIToUTF16("Cynthia Love");
  profile->SetMultiInfo(NAME_FULL, multi_values);
  autofill_manager_->AddProfile(profile);

  // Get the first name field.  And start out with "Cy", hoping for "Cynthia".
  FormField& field = form.fields[0];
  field.value = ASCIIToUTF16("Cy");
  field.is_autofilled = false;
  GetAutofillSuggestions(form, field);

  // Trigger the |Send|.
  AutocompleteSuggestionsReturned(std::vector<string16>());

  // Test that we sent the right message to the renderer.
  int page_id = 0;
  std::vector<string16> values;
  std::vector<string16> labels;
  std::vector<string16> icons;
  std::vector<int> unique_ids;
  EXPECT_TRUE(GetAutofillSuggestionsMessage(&page_id, &values, &labels, &icons,
                                            &unique_ids));

  string16 expected_values[] = { ASCIIToUTF16("Cynthia") };
  string16 expected_labels[] = { ASCIIToUTF16("me@x.com") };
  string16 expected_icons[] = { string16() };
  int expected_unique_ids[] = { 101 };
  ExpectSuggestions(page_id, values, labels, icons, unique_ids,
                    kDefaultPageID, arraysize(expected_values), expected_values,
                    expected_labels, expected_icons, expected_unique_ids);
}

// Test that all values are suggested for multi-valued profile, on a filled
// form.  This is the per-field "override" case.
TEST_F(AutofillManagerTest, GetFieldSuggestionsForMultiValuedProfileFilled) {
  // Set up our form data.
  FormData form;
  CreateTestAddressFormData(&form);
  std::vector<FormData> forms(1, form);
  FormsSeen(forms);

  // |profile| will be owned by the mock PersonalDataManager.
  AutofillProfile* profile = new AutofillProfile;
  profile->set_guid("00000000-0000-0000-0000-000000000102");
  std::vector<string16> multi_values(3);
  multi_values[0] = ASCIIToUTF16("Travis Smith");
  multi_values[1] = ASCIIToUTF16("Cynthia Love");
  multi_values[2] = ASCIIToUTF16("Zac Mango");
  profile->SetMultiInfo(NAME_FULL, multi_values);
  autofill_manager_->AddProfile(profile);

  // Get the first name field.  And start out with "Travis", hoping for all the
  // multi-valued variants as suggestions.
  FormField& field = form.fields[0];
  field.value = ASCIIToUTF16("Travis");
  field.is_autofilled = true;
  GetAutofillSuggestions(form, field);

  // Trigger the |Send|.
  AutocompleteSuggestionsReturned(std::vector<string16>());

  // Test that we sent the right message to the renderer.
  int page_id = 0;
  std::vector<string16> values;
  std::vector<string16> labels;
  std::vector<string16> icons;
  std::vector<int> unique_ids;
  EXPECT_TRUE(GetAutofillSuggestionsMessage(&page_id, &values, &labels, &icons,
                                            &unique_ids));

  string16 expected_values[] = {
    ASCIIToUTF16("Travis"),
    ASCIIToUTF16("Cynthia"),
    ASCIIToUTF16("Zac")
  };
  string16 expected_labels[] = { string16(), string16(), string16() };
  string16 expected_icons[] = { string16(), string16(), string16() };
  int expected_unique_ids[] = { 102, 102, 102 };
  ExpectSuggestions(page_id, values, labels, icons, unique_ids,
                    kDefaultPageID, arraysize(expected_values), expected_values,
                    expected_labels, expected_icons, expected_unique_ids);
}

// Test that we correctly fill an address form.
TEST_F(AutofillManagerTest, FillAddressForm) {
  // Set up our form data.
  FormData form;
  CreateTestAddressFormData(&form);
  std::vector<FormData> forms(1, form);
  FormsSeen(forms);

  GUIDPair guid("00000000-0000-0000-0000-000000000001", 0);
  GUIDPair empty(std::string(), 0);
  FillAutofillFormData(
      kDefaultPageID, form, form.fields[0],
      autofill_manager_->PackGUIDs(empty, guid));

  int page_id = 0;
  FormData results;
  EXPECT_TRUE(GetAutofillFormDataFilledMessage(&page_id, &results));
  ExpectFilledAddressFormElvis(page_id, results, kDefaultPageID, false);
}

// Test that we correctly fill a credit card form.
TEST_F(AutofillManagerTest, FillCreditCardForm) {
  // Set up our form data.
  FormData form;
  CreateTestCreditCardFormData(&form, true, false);
  std::vector<FormData> forms(1, form);
  FormsSeen(forms);

  GUIDPair guid("00000000-0000-0000-0000-000000000004", 0);
  GUIDPair empty(std::string(), 0);
  FillAutofillFormData(
      kDefaultPageID, form, *form.fields.begin(),
      autofill_manager_->PackGUIDs(guid, empty));

  int page_id = 0;
  FormData results;
  EXPECT_TRUE(GetAutofillFormDataFilledMessage(&page_id, &results));
  ExpectFilledCreditCardFormElvis(page_id, results, kDefaultPageID, false);
}

// Test that we correctly fill a credit card form with month input type.
// 1. year empty, month empty
TEST_F(AutofillManagerTest, FillCreditCardFormNoYearNoMonth) {
  // Same as the SetUp(), but generate 4 credit cards with year month
  // combination.
  test_personal_data_->CreateTestCreditCardsYearAndMonth("", "");
  // Set up our form data.
  FormData form;
  CreateTestCreditCardFormData(&form, true, true);
  std::vector<FormData> forms(1, form);
  FormsSeen(forms);

  GUIDPair guid("00000000-0000-0000-0000-000000000007", 0);
  GUIDPair empty(std::string(), 0);
  FillAutofillFormData(
      kDefaultPageID, form, *form.fields.begin(),
      autofill_manager_->PackGUIDs(guid, empty));

  int page_id = 0;
  FormData results;
  EXPECT_TRUE(GetAutofillFormDataFilledMessage(&page_id, &results));
  ExpectFilledCreditCardYearMonthWithYearMonth(page_id, results,
      kDefaultPageID, false, "", "");
}


// Test that we correctly fill a credit card form with month input type.
// 2. year empty, month non-empty
TEST_F(AutofillManagerTest, FillCreditCardFormNoYearMonth) {
  // Same as the SetUp(), but generate 4 credit cards with year month
  // combination.
  test_personal_data_->CreateTestCreditCardsYearAndMonth("", "04");
  // Set up our form data.
  FormData form;
  CreateTestCreditCardFormData(&form, true, true);
  std::vector<FormData> forms(1, form);
  FormsSeen(forms);

  GUIDPair guid("00000000-0000-0000-0000-000000000007", 0);
  GUIDPair empty(std::string(), 0);
  FillAutofillFormData(
      kDefaultPageID, form, *form.fields.begin(),
      autofill_manager_->PackGUIDs(guid, empty));

  int page_id = 0;
  FormData results;
  EXPECT_TRUE(GetAutofillFormDataFilledMessage(&page_id, &results));
  ExpectFilledCreditCardYearMonthWithYearMonth(page_id, results,
      kDefaultPageID, false, "", "04");
}

// Test that we correctly fill a credit card form with month input type.
// 3. year non-empty, month empty
TEST_F(AutofillManagerTest, FillCreditCardFormYearNoMonth) {
  // Same as the SetUp(), but generate 4 credit cards with year month
  // combination.
  test_personal_data_->CreateTestCreditCardsYearAndMonth("2012", "");
  // Set up our form data.
  FormData form;
  CreateTestCreditCardFormData(&form, true, true);
  std::vector<FormData> forms(1, form);
  FormsSeen(forms);

  GUIDPair guid("00000000-0000-0000-0000-000000000007", 0);
  GUIDPair empty(std::string(), 0);
  FillAutofillFormData(
      kDefaultPageID, form, *form.fields.begin(),
      autofill_manager_->PackGUIDs(guid, empty));

  int page_id = 0;
  FormData results;
  EXPECT_TRUE(GetAutofillFormDataFilledMessage(&page_id, &results));
  ExpectFilledCreditCardYearMonthWithYearMonth(page_id, results,
      kDefaultPageID, false, "2012", "");
}

// Test that we correctly fill a credit card form with month input type.
// 4. year non-empty, month empty
TEST_F(AutofillManagerTest, FillCreditCardFormYearMonth) {
  // Same as the SetUp(), but generate 4 credit cards with year month
  // combination.
  test_personal_data_->ClearCreditCards();
  test_personal_data_->CreateTestCreditCardsYearAndMonth("2012", "04");
  // Set up our form data.
  FormData form;
  CreateTestCreditCardFormData(&form, true, true);
  std::vector<FormData> forms(1, form);
  FormsSeen(forms);

  GUIDPair guid("00000000-0000-0000-0000-000000000007", 0);
  GUIDPair empty(std::string(), 0);
  FillAutofillFormData(
      kDefaultPageID, form, *form.fields.begin(),
      autofill_manager_->PackGUIDs(guid, empty));

  int page_id = 0;
  FormData results;
  EXPECT_TRUE(GetAutofillFormDataFilledMessage(&page_id, &results));
  ExpectFilledCreditCardYearMonthWithYearMonth(page_id, results,
      kDefaultPageID, false, "2012", "04");
}

// Test that we correctly fill a combined address and credit card form.
TEST_F(AutofillManagerTest, FillAddressAndCreditCardForm) {
  // Set up our form data.
  FormData form;
  CreateTestAddressFormData(&form);
  CreateTestCreditCardFormData(&form, true, false);
  std::vector<FormData> forms(1, form);
  FormsSeen(forms);

  // First fill the address data.
  GUIDPair guid("00000000-0000-0000-0000-000000000001", 0);
  GUIDPair empty(std::string(), 0);
  FillAutofillFormData(kDefaultPageID, form, form.fields[0],
                       autofill_manager_->PackGUIDs(empty, guid));

  int page_id = 0;
  FormData results;
  EXPECT_TRUE(GetAutofillFormDataFilledMessage(&page_id, &results));
  {
    SCOPED_TRACE("Address");
    ExpectFilledAddressFormElvis(page_id, results, kDefaultPageID, true);
  }

  // Now fill the credit card data.
  const int kPageID2 = 2;
  GUIDPair guid2("00000000-0000-0000-0000-000000000004", 0);
  FillAutofillFormData(
      kPageID2, form, form.fields.back(),
      autofill_manager_->PackGUIDs(guid2, empty));

  page_id = 0;
  EXPECT_TRUE(GetAutofillFormDataFilledMessage(&page_id, &results));
  {
    SCOPED_TRACE("Credit card");
    ExpectFilledCreditCardFormElvis(page_id, results, kPageID2, true);
  }
}

// Test that we correctly fill a form that has multiple logical sections, e.g.
// both a billing and a shipping address.
TEST_F(AutofillManagerTest, FillFormWithMultipleSections) {
  // Set up our form data.
  FormData form;
  CreateTestAddressFormData(&form);
  const size_t kAddressFormSize = form.fields.size();
  CreateTestAddressFormData(&form);
  for (size_t i = kAddressFormSize; i < form.fields.size(); ++i) {
    // Make sure the fields have distinct names.
    form.fields[i].name = form.fields[i].name + ASCIIToUTF16("_");
  }
  std::vector<FormData> forms(1, form);
  FormsSeen(forms);

  // Fill the first section.
  GUIDPair guid("00000000-0000-0000-0000-000000000001", 0);
  GUIDPair empty(std::string(), 0);
  FillAutofillFormData(kDefaultPageID, form, form.fields[0],
                       autofill_manager_->PackGUIDs(empty, guid));

  int page_id = 0;
  FormData results;
  EXPECT_TRUE(GetAutofillFormDataFilledMessage(&page_id, &results));
  {
    SCOPED_TRACE("Address 1");

    // The second address section should be empty.
    ASSERT_EQ(results.fields.size(), 2*kAddressFormSize);
    for (size_t i = kAddressFormSize; i < form.fields.size(); ++i) {
      EXPECT_EQ(string16(), results.fields[i].value);
    }

    // The first address section should be filled with Elvis's data.
    results.fields.resize(kAddressFormSize);
    ExpectFilledAddressFormElvis(page_id, results, kDefaultPageID, false);
  }

  // Fill the second section, with the initiating field somewhere in the middle
  // of the section.
  const int kPageID2 = 2;
  GUIDPair guid2("00000000-0000-0000-0000-000000000001", 0);
  ASSERT_LT(9U, kAddressFormSize);
  FillAutofillFormData(kPageID2, form, form.fields[kAddressFormSize + 9],
                       autofill_manager_->PackGUIDs(empty, guid2));

  page_id = 0;
  EXPECT_TRUE(GetAutofillFormDataFilledMessage(&page_id, &results));
  {
    SCOPED_TRACE("Address 2");
    ASSERT_EQ(results.fields.size(), form.fields.size());

    // The first address section should be empty.
    ASSERT_EQ(results.fields.size(), 2*kAddressFormSize);
    for (size_t i = 0; i < kAddressFormSize; ++i) {
      EXPECT_EQ(string16(), results.fields[i].value);
    }

    // The second address section should be filled with Elvis's data.
    FormData secondSection = results;
    secondSection.fields.erase(secondSection.fields.begin(),
                               secondSection.fields.begin() + kAddressFormSize);
    for (size_t i = 0; i < kAddressFormSize; ++i) {
      // Restore the expected field names.
      string16 name = secondSection.fields[i].name;
      string16 original_name = name.substr(0, name.size() - 1);
      secondSection.fields[i].name = original_name;
    }
    ExpectFilledAddressFormElvis(page_id, secondSection, kPageID2, false);
  }
}

// Test that we correctly fill a form that has a single logical section with
// multiple email address fields.
TEST_F(AutofillManagerTest, FillFormWithMultipleEmails) {
  // Set up our form data.
  FormData form;
  CreateTestAddressFormData(&form);
  FormField field;
  autofill_test::CreateTestFormField(
      "Confirm email", "email2", "", "text", &field);
  form.fields.push_back(field);

  std::vector<FormData> forms(1, form);
  FormsSeen(forms);

  // Fill the form.
  GUIDPair guid("00000000-0000-0000-0000-000000000001", 0);
  GUIDPair empty(std::string(), 0);
  FillAutofillFormData(kDefaultPageID, form, form.fields[0],
                       autofill_manager_->PackGUIDs(empty, guid));

  int page_id = 0;
  FormData results;
  EXPECT_TRUE(GetAutofillFormDataFilledMessage(&page_id, &results));

  // The second email address should be filled.
  EXPECT_EQ(ASCIIToUTF16("theking@gmail.com"), results.fields.back().value);

  // The remainder of the form should be filled as usual.
  results.fields.pop_back();
  ExpectFilledAddressFormElvis(page_id, results, kDefaultPageID, false);
}

// Test that we correctly fill a previously auto-filled form.
TEST_F(AutofillManagerTest, FillAutofilledForm) {
  // Set up our form data.
  FormData form;
  CreateTestAddressFormData(&form);
  // Mark one of the address fields as autofilled.
  form.fields[4].is_autofilled = true;
  CreateTestCreditCardFormData(&form, true, false);
  std::vector<FormData> forms(1, form);
  FormsSeen(forms);

  // First fill the address data.
  GUIDPair guid("00000000-0000-0000-0000-000000000001", 0);
  GUIDPair empty(std::string(), 0);
  FillAutofillFormData(
      kDefaultPageID, form, *form.fields.begin(),
      autofill_manager_->PackGUIDs(empty, guid));

  int page_id = 0;
  FormData results;
  EXPECT_TRUE(GetAutofillFormDataFilledMessage(&page_id, &results));
  {
    SCOPED_TRACE("Address");
    ExpectFilledForm(page_id, results, kDefaultPageID,
                     "Elvis", "", "", "", "", "", "", "", "", "", "", "",
                     "", "", "", "", true, true, false);
  }

  // Now fill the credit card data.
  const int kPageID2 = 2;
  GUIDPair guid2("00000000-0000-0000-0000-000000000004", 0);
  FillAutofillFormData(
      kPageID2, form, form.fields.back(),
      autofill_manager_->PackGUIDs(guid2, empty));

  page_id = 0;
  EXPECT_TRUE(GetAutofillFormDataFilledMessage(&page_id, &results));
  {
    SCOPED_TRACE("Credit card 1");
    ExpectFilledCreditCardFormElvis(page_id, results, kPageID2, true);
  }

  // Now set the credit card fields to also be auto-filled, and try again to
  // fill the credit card data
  for (std::vector<FormField>::iterator iter = form.fields.begin();
       iter != form.fields.end();
       ++iter) {
    iter->is_autofilled = true;
  }

  const int kPageID3 = 3;
  FillAutofillFormData(
      kPageID3, form, *form.fields.rbegin(),
      autofill_manager_->PackGUIDs(guid2, empty));

  page_id = 0;
  EXPECT_TRUE(GetAutofillFormDataFilledMessage(&page_id, &results));
  {
    SCOPED_TRACE("Credit card 2");
    ExpectFilledForm(page_id, results, kPageID3,
                   "", "", "", "", "", "", "", "", "", "", "", "",
                   "", "", "", "2012", true, true, false);
  }
}

// Test that we correctly fill a phone number split across multiple fields.
TEST_F(AutofillManagerTest, FillPhoneNumber) {
  // Set up our form data.
  FormData form;
  form.name = ASCIIToUTF16("MyPhoneForm");
  form.method = ASCIIToUTF16("POST");
  form.origin = GURL("http://myform.com/phone_form.html");
  form.action = GURL("http://myform.com/phone_submit.html");
  form.user_submitted = true;

  FormField field;
  autofill_test::CreateTestFormField(
      "country code", "country code", "", "text", &field);
  field.max_length = 1;
  form.fields.push_back(field);
  autofill_test::CreateTestFormField(
      "area code", "area code", "", "text", &field);
  field.max_length = 3;
  form.fields.push_back(field);
  autofill_test::CreateTestFormField(
      "phone", "phone prefix", "1", "text", &field);
  field.max_length = 3;
  form.fields.push_back(field);
  autofill_test::CreateTestFormField(
      "-", "phone suffix", "", "text", &field);
  field.max_length = 4;
  form.fields.push_back(field);
  autofill_test::CreateTestFormField(
      "Phone Extension", "ext", "", "text", &field);
  field.max_length = 3;
  form.fields.push_back(field);

  std::vector<FormData> forms(1, form);
  FormsSeen(forms);

  AutofillProfile *work_profile = autofill_manager_->GetProfileWithGUID(
      "00000000-0000-0000-0000-000000000002");
  ASSERT_TRUE(work_profile != NULL);
  string16 saved_phone = work_profile->GetInfo(PHONE_HOME_NUMBER);

  GUIDPair guid(work_profile->guid(), 0);
  GUIDPair empty(std::string(), 0);

  char test_data[] = "1234567890123456";
  for (int i = arraysize(test_data) - 1; i >= 0; --i) {
    test_data[i] = 0;
    SCOPED_TRACE(StringPrintf("Testing phone: %s", test_data));
    work_profile->SetInfo(PHONE_HOME_NUMBER, ASCIIToUTF16(test_data));
    // The page ID sent to the AutofillManager from the RenderView, used to send
    // an IPC message back to the renderer.
    int page_id = 100 - i;
    FillAutofillFormData(
        page_id, form, *form.fields.begin(),
        autofill_manager_->PackGUIDs(empty, guid));
    page_id = 0;
    FormData results;
    EXPECT_TRUE(GetAutofillFormDataFilledMessage(&page_id, &results));

    if (i != 7) {
      EXPECT_EQ(ASCIIToUTF16(test_data), results.fields[2].value);
      EXPECT_EQ(ASCIIToUTF16(test_data), results.fields[3].value);
    } else {
      // The only size that is parsed and split, right now is 7:
      EXPECT_EQ(ASCIIToUTF16("123"), results.fields[2].value);
      EXPECT_EQ(ASCIIToUTF16("4567"), results.fields[3].value);
    }
  }

  work_profile->SetInfo(PHONE_HOME_NUMBER, saved_phone);
}

// Test that we can still fill a form when a field has been removed from it.
TEST_F(AutofillManagerTest, FormChangesRemoveField) {
  // Set up our form data.
  FormData form;
  CreateTestAddressFormData(&form);

  // Add a field -- we'll remove it again later.
  FormField field;
  autofill_test::CreateTestFormField("Some", "field", "", "text", &field);
  form.fields.insert(form.fields.begin() + 3, field);

  std::vector<FormData> forms(1, form);
  FormsSeen(forms);

  // Now, after the call to |FormsSeen|, we remove the field before filling.
  form.fields.erase(form.fields.begin() + 3);

  GUIDPair guid("00000000-0000-0000-0000-000000000001", 0);
  GUIDPair empty(std::string(), 0);
  FillAutofillFormData(
      kDefaultPageID, form, form.fields[0],
      autofill_manager_->PackGUIDs(empty, guid));

  int page_id = 0;
  FormData results;
  EXPECT_TRUE(GetAutofillFormDataFilledMessage(&page_id, &results));
  ExpectFilledAddressFormElvis(page_id, results, kDefaultPageID, false);
}

// Test that we can still fill a form when a field has been added to it.
TEST_F(AutofillManagerTest, FormChangesAddField) {
  // The offset of the fax field in the address form.
  const int kFaxFieldOffset = 10;

  // Set up our form data.
  FormData form;
  CreateTestAddressFormData(&form);

  // Remove the fax field -- we'll add it back later.
  std::vector<FormField>::iterator pos = form.fields.begin() + kFaxFieldOffset;
  FormField field = *pos;
  pos = form.fields.erase(pos);

  std::vector<FormData> forms(1, form);
  FormsSeen(forms);

  // Now, after the call to |FormsSeen|, we restore the field before filling.
  form.fields.insert(pos, field);

  GUIDPair guid("00000000-0000-0000-0000-000000000001", 0);
  GUIDPair empty(std::string(), 0);
  FillAutofillFormData(
      kDefaultPageID, form, form.fields[0],
      autofill_manager_->PackGUIDs(empty, guid));

  int page_id = 0;
  FormData results;
  EXPECT_TRUE(GetAutofillFormDataFilledMessage(&page_id, &results));
  ExpectFilledAddressFormElvis(page_id, results, kDefaultPageID, false);
}

// Test that we are able to save form data when forms are submitted.
TEST_F(AutofillManagerTest, FormSubmitted) {
  // Set up our form data.
  FormData form;
  CreateTestAddressFormData(&form);
  std::vector<FormData> forms(1, form);
  FormsSeen(forms);

  // Fill the form.
  GUIDPair guid("00000000-0000-0000-0000-000000000001", 0);
  GUIDPair empty(std::string(), 0);
  FillAutofillFormData(kDefaultPageID, form, form.fields[0],
                       autofill_manager_->PackGUIDs(empty, guid));

  int page_id = 0;
  FormData results;
  EXPECT_TRUE(GetAutofillFormDataFilledMessage(&page_id, &results));
  ExpectFilledAddressFormElvis(page_id, results, kDefaultPageID, false);

  // Simulate form submission. We should call into the PDM to try to save the
  // filled data.
  EXPECT_CALL(*test_personal_data_, SaveImportedProfile(::testing::_)).Times(1);
  FormSubmitted(results);
}

// Test that we are able to save form data when forms are submitted and we only
// have server data for the field types.
TEST_F(AutofillManagerTest, FormSubmittedServerTypes) {
  // Set up our form data.
  FormData form;
  CreateTestAddressFormData(&form);

  // Simulate having seen this form on page load.
  // |form_structure| will be owned by |autofill_manager_|.
  TestFormStructure* form_structure = new TestFormStructure(form);
  form_structure->DetermineHeuristicTypes();

  // Clear the heuristic types, and instead set the appropriate server types.
  std::vector<AutofillFieldType> heuristic_types, server_types;
  for (size_t i = 0; i < form.fields.size(); ++i) {
    heuristic_types.push_back(UNKNOWN_TYPE);
    server_types.push_back(form_structure->field(i)->type());
  }
  form_structure->SetFieldTypes(heuristic_types, server_types);
  autofill_manager_->AddSeenForm(form_structure);

  // Fill the form.
  GUIDPair guid("00000000-0000-0000-0000-000000000001", 0);
  GUIDPair empty(std::string(), 0);
  FillAutofillFormData(kDefaultPageID, form, form.fields[0],
                       autofill_manager_->PackGUIDs(empty, guid));

  int page_id = 0;
  FormData results;
  EXPECT_TRUE(GetAutofillFormDataFilledMessage(&page_id, &results));
  ExpectFilledAddressFormElvis(page_id, results, kDefaultPageID, false);

  // Simulate form submission. We should call into the PDM to try to save the
  // filled data.
  EXPECT_CALL(*test_personal_data_, SaveImportedProfile(::testing::_)).Times(1);
  FormSubmitted(results);
}

// Checks that resetting the auxiliary profile enabled preference does the right
// thing on all platforms.
TEST_F(AutofillManagerTest, AuxiliaryProfilesReset) {
#if defined(OS_MACOSX)
  // Auxiliary profiles is implemented on Mac only.  It enables Mac Address
  // Book integration.
  ASSERT_TRUE(profile()->GetPrefs()->GetBoolean(
      prefs::kAutofillAuxiliaryProfilesEnabled));
  profile()->GetPrefs()->SetBoolean(
      prefs::kAutofillAuxiliaryProfilesEnabled, false);
  profile()->GetPrefs()->ClearPref(prefs::kAutofillAuxiliaryProfilesEnabled);
  ASSERT_TRUE(profile()->GetPrefs()->GetBoolean(
      prefs::kAutofillAuxiliaryProfilesEnabled));
#else
  ASSERT_FALSE(profile()->GetPrefs()->GetBoolean(
      prefs::kAutofillAuxiliaryProfilesEnabled));
  profile()->GetPrefs()->SetBoolean(
      prefs::kAutofillAuxiliaryProfilesEnabled, true);
  profile()->GetPrefs()->ClearPref(prefs::kAutofillAuxiliaryProfilesEnabled);
  ASSERT_FALSE(profile()->GetPrefs()->GetBoolean(
      prefs::kAutofillAuxiliaryProfilesEnabled));
#endif
}