// found in the LICENSE file.
#include "base/basictypes.h"
+#include "base/format_macros.h"
#include "base/guid.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "base/stl_util.h"
#include "base/strings/string16.h"
+#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/browser/autofill_profile.h"
#include "components/autofill/core/browser/autofill_test_utils.h"
#include "components/autofill/core/browser/autofill_type.h"
+#include "components/autofill/core/browser/field_types.h"
#include "components/autofill/core/common/form_field_data.h"
-#include "grit/component_strings.h"
#include "testing/gtest/include/gtest/gtest.h"
using base::ASCIIToUTF16;
+using base::UTF8ToUTF16;
namespace autofill {
std::vector<AutofillProfile*> profiles;
profiles.push_back(profile);
std::vector<base::string16> labels;
- AutofillProfile::CreateDifferentiatingLabels(profiles, &labels);
+ AutofillProfile::CreateDifferentiatingLabels(profiles, "en-US", &labels);
return labels[0];
}
+// Holds the autofill profile |first|, |middle| and |last| names.
+struct NameParts {
+ NameParts(const std::string& first,
+ const std::string& middle,
+ const std::string& last)
+ : first(first), middle(middle), last(last) {}
+
+ std::string first;
+ std::string middle;
+ std::string last;
+};
+
+// Test case to be executed to validate OverwriteOrAppendNames.
+struct TestCase {
+ TestCase(const NameParts& starting_name,
+ const NameParts& additional_name,
+ const NameParts& expected_result)
+ : starting_names(std::vector<NameParts>(1, starting_name)),
+ additional_names(std::vector<NameParts>(1, additional_name)),
+ expected_result(std::vector<NameParts>(1, expected_result)) {}
+
+ TestCase(const std::vector<NameParts>& starting_names,
+ const std::vector<NameParts>& additional_names,
+ const std::vector<NameParts>& expected_result)
+ : starting_names(starting_names),
+ additional_names(additional_names),
+ expected_result(expected_result) {}
+
+ std::vector<NameParts> starting_names;
+ std::vector<NameParts> additional_names;
+ std::vector<NameParts> expected_result;
+};
+
+// Populates |first_names|, |middle_names| and |last_names| from the list of
+// NameParts from |starting_names|, |additional_names| or |expected_result|
+// from the testcase to create and verify the autofill profile.
+void GetNamePartsList(const std::vector<NameParts>& names,
+ std::vector<base::string16>* first_names,
+ std::vector<base::string16>* middle_names,
+ std::vector<base::string16>* last_names) {
+ for (size_t i = 0; i < names.size(); ++i) {
+ first_names->push_back(ASCIIToUTF16(names[i].first));
+ middle_names->push_back(ASCIIToUTF16(names[i].middle));
+ last_names->push_back(ASCIIToUTF16(names[i].last));
+ }
+}
+
} // namespace
// Tests different possibilities for summary string generation.
profiles.push_back(&profile7);
profiles.push_back(&profile7a);
std::vector<base::string16> labels;
- AutofillProfile::CreateDifferentiatingLabels(profiles, &labels);
+ AutofillProfile::CreateDifferentiatingLabels(profiles, "en-US", &labels);
ASSERT_EQ(profiles.size(), labels.size());
summary7 = labels[0];
base::string16 summary7a = labels[1];
"US",
"12345678910");
std::vector<base::string16> labels;
- AutofillProfile::CreateDifferentiatingLabels(profiles.get(), &labels);
+ AutofillProfile::CreateDifferentiatingLabels(
+ profiles.get(), "en-US", &labels);
ASSERT_EQ(2U, labels.size());
EXPECT_EQ(ASCIIToUTF16("John Doe, 666 Erebus St."), labels[0]);
EXPECT_EQ(ASCIIToUTF16("Jane Doe, 123 Letha Shore."), labels[1]);
"US",
"16502111111");
labels.clear();
- AutofillProfile::CreateDifferentiatingLabels(profiles.get(), &labels);
+ AutofillProfile::CreateDifferentiatingLabels(
+ profiles.get(), "en-US", &labels);
// Profile 0 and 2 inferred label now includes an e-mail.
ASSERT_EQ(3U, labels.size());
"16502111111");
labels.clear();
- AutofillProfile::CreateDifferentiatingLabels(profiles.get(), &labels);
+ AutofillProfile::CreateDifferentiatingLabels(
+ profiles.get(), "en-US", &labels);
// Profile 0 and 2 inferred label now includes a state.
ASSERT_EQ(3U, labels.size());
"16504444444"); // Phone is different for some.
labels.clear();
- AutofillProfile::CreateDifferentiatingLabels(profiles.get(), &labels);
+ AutofillProfile::CreateDifferentiatingLabels(
+ profiles.get(), "en-US", &labels);
ASSERT_EQ(4U, labels.size());
EXPECT_EQ(ASCIIToUTF16("John Doe, 666 Erebus St., CA"), labels[0]);
EXPECT_EQ(ASCIIToUTF16("Jane Doe, 123 Letha Shore."), labels[1]);
"16504444444"); // Phone is different for some.
labels.clear();
- AutofillProfile::CreateDifferentiatingLabels(profiles.get(), &labels);
+ AutofillProfile::CreateDifferentiatingLabels(
+ profiles.get(), "en-US", &labels);
ASSERT_EQ(5U, labels.size());
EXPECT_EQ(ASCIIToUTF16("John Doe, 666 Erebus St., CA"), labels[0]);
EXPECT_EQ(ASCIIToUTF16("Jane Doe, 123 Letha Shore."), labels[1]);
labels[4]);
}
+TEST(AutofillProfileTest, CreateInferredLabelsI18n_CH) {
+ ScopedVector<AutofillProfile> profiles;
+ profiles.push_back(
+ new AutofillProfile(base::GenerateGUID(), "https://www.example.com/"));
+ test::SetProfileInfo(profiles.back(),
+ "H.",
+ "R.",
+ "Giger",
+ "hrgiger@beispiel.com",
+ "Beispiel Inc",
+ "Brandschenkestrasse 110",
+ "",
+ "Zurich", "",
+ "8002",
+ "CH",
+ "+41 44-668-1800");
+ profiles.back()->set_language_code("de_CH");
+ static const char* kExpectedLabels[] = {
+ "",
+ "H. R. Giger",
+ "H. R. Giger, Brandschenkestrasse 110",
+ "H. R. Giger, Brandschenkestrasse 110, Zurich",
+ "H. R. Giger, Brandschenkestrasse 110, CH-8002 Zurich",
+ "Beispiel Inc, H. R. Giger, Brandschenkestrasse 110, CH-8002 Zurich",
+ "Beispiel Inc, H. R. Giger, Brandschenkestrasse 110, CH-8002 Zurich, "
+ "Switzerland",
+ "Beispiel Inc, H. R. Giger, Brandschenkestrasse 110, CH-8002 Zurich, "
+ "Switzerland, hrgiger@beispiel.com",
+ "Beispiel Inc, H. R. Giger, Brandschenkestrasse 110, CH-8002 Zurich, "
+ "Switzerland, hrgiger@beispiel.com, +41446681800",
+ };
+
+ std::vector<base::string16> labels;
+ for (size_t i = 0; i < arraysize(kExpectedLabels); ++i) {
+ AutofillProfile::CreateInferredLabels(
+ profiles.get(), NULL, UNKNOWN_TYPE, i, "en-US", &labels);
+ ASSERT_FALSE(labels.empty());
+ EXPECT_EQ(UTF8ToUTF16(kExpectedLabels[i]), labels.back());
+ }
+}
+
+
+TEST(AutofillProfileTest, CreateInferredLabelsI18n_FR) {
+ ScopedVector<AutofillProfile> profiles;
+ profiles.push_back(
+ new AutofillProfile(base::GenerateGUID(), "https://www.example.com/"));
+ test::SetProfileInfo(profiles.back(),
+ "Antoine",
+ "",
+ "de Saint-Exupéry",
+ "antoine@exemple.com",
+ "Exemple Inc",
+ "8 Rue de Londres",
+ "",
+ "Paris", "",
+ "75009",
+ "FR",
+ "+33 (0) 1 42 68 53 00");
+ profiles.back()->set_language_code("fr_FR");
+ profiles.back()->SetInfo(
+ AutofillType(ADDRESS_HOME_SORTING_CODE), UTF8ToUTF16("CEDEX"), "en-US");
+ static const char* kExpectedLabels[] = {
+ "",
+ "Antoine de Saint-Exupéry",
+ "Antoine de Saint-Exupéry, 8 Rue de Londres",
+ "Antoine de Saint-Exupéry, 8 Rue de Londres, Paris",
+ "Antoine de Saint-Exupéry, 8 Rue de Londres, 75009 Paris",
+ "Antoine de Saint-Exupéry, 8 Rue de Londres, 75009 Paris CEDEX",
+ "Exemple Inc, Antoine de Saint-Exupéry, 8 Rue de Londres, 75009 Paris "
+ "CEDEX",
+ "Exemple Inc, Antoine de Saint-Exupéry, 8 Rue de Londres, 75009 Paris "
+ "CEDEX, France",
+ "Exemple Inc, Antoine de Saint-Exupéry, 8 Rue de Londres, 75009 Paris "
+ "CEDEX, France, antoine@exemple.com",
+ "Exemple Inc, Antoine de Saint-Exupéry, 8 Rue de Londres, 75009 Paris "
+ "CEDEX, France, antoine@exemple.com, +33142685300",
+ "Exemple Inc, Antoine de Saint-Exupéry, 8 Rue de Londres, 75009 Paris "
+ "CEDEX, France, antoine@exemple.com, +33142685300",
+ };
+
+ std::vector<base::string16> labels;
+ for (size_t i = 0; i < arraysize(kExpectedLabels); ++i) {
+ AutofillProfile::CreateInferredLabels(
+ profiles.get(), NULL, UNKNOWN_TYPE, i, "en-US", &labels);
+ ASSERT_FALSE(labels.empty());
+ EXPECT_EQ(UTF8ToUTF16(kExpectedLabels[i]), labels.back());
+ }
+}
+
+TEST(AutofillProfileTest, CreateInferredLabelsI18n_KR) {
+ ScopedVector<AutofillProfile> profiles;
+ profiles.push_back(
+ new AutofillProfile(base::GenerateGUID(), "https://www.example.com/"));
+ test::SetProfileInfo(profiles.back(),
+ "Park",
+ "",
+ "Jae-sang",
+ "park@yeleul.com",
+ "Yeleul Inc",
+ "Gangnam Finance Center",
+ "152 Teheran-ro",
+ "Gangnam-Gu", "Seoul",
+ "135-984",
+ "KR",
+ "+82-2-531-9000");
+ profiles.back()->set_language_code("ko_Latn");
+ profiles.back()->SetInfo(AutofillType(ADDRESS_HOME_DEPENDENT_LOCALITY),
+ UTF8ToUTF16("Yeoksam-Dong"),
+ "en-US");
+ static const char* kExpectedLabels[] = {
+ "",
+ "Park Jae-sang",
+ "Park Jae-sang, Gangnam Finance Center",
+ "Park Jae-sang, Gangnam Finance Center, 152 Teheran-ro",
+ "Park Jae-sang, Gangnam Finance Center, 152 Teheran-ro, Yeoksam-Dong",
+ "Park Jae-sang, Gangnam Finance Center, 152 Teheran-ro, Yeoksam-Dong, "
+ "Gangnam-Gu",
+ "Park Jae-sang, Gangnam Finance Center, 152 Teheran-ro, Yeoksam-Dong, "
+ "Gangnam-Gu, Seoul",
+ "Park Jae-sang, Gangnam Finance Center, 152 Teheran-ro, Yeoksam-Dong, "
+ "Gangnam-Gu, Seoul, 135-984",
+ "Park Jae-sang, Yeleul Inc, Gangnam Finance Center, 152 Teheran-ro, "
+ "Yeoksam-Dong, Gangnam-Gu, Seoul, 135-984",
+ "Park Jae-sang, Yeleul Inc, Gangnam Finance Center, 152 Teheran-ro, "
+ "Yeoksam-Dong, Gangnam-Gu, Seoul, 135-984, South Korea",
+ "Park Jae-sang, Yeleul Inc, Gangnam Finance Center, 152 Teheran-ro, "
+ "Yeoksam-Dong, Gangnam-Gu, Seoul, 135-984, South Korea, "
+ "park@yeleul.com",
+ "Park Jae-sang, Yeleul Inc, Gangnam Finance Center, 152 Teheran-ro, "
+ "Yeoksam-Dong, Gangnam-Gu, Seoul, 135-984, South Korea, "
+ "park@yeleul.com, +8225319000",
+ };
+
+ std::vector<base::string16> labels;
+ for (size_t i = 0; i < arraysize(kExpectedLabels); ++i) {
+ AutofillProfile::CreateInferredLabels(
+ profiles.get(), NULL, UNKNOWN_TYPE, i, "en-US", &labels);
+ ASSERT_FALSE(labels.empty());
+ EXPECT_EQ(UTF8ToUTF16(kExpectedLabels[i]), labels.back());
+ }
+}
+
+TEST(AutofillProfileTest, CreateInferredLabelsI18n_JP_Latn) {
+ ScopedVector<AutofillProfile> profiles;
+ profiles.push_back(
+ new AutofillProfile(base::GenerateGUID(), "https://www.example.com/"));
+ test::SetProfileInfo(profiles.back(),
+ "Miku",
+ "",
+ "Hatsune",
+ "miku@rei.com",
+ "Rei Inc",
+ "Roppongi Hills Mori Tower",
+ "6-10-1 Roppongi",
+ "Minato-ku", "Tokyo",
+ "106-6126",
+ "JP",
+ "+81-3-6384-9000");
+ profiles.back()->set_language_code("ja_Latn");
+ static const char* kExpectedLabels[] = {
+ "",
+ "Miku Hatsune",
+ "Miku Hatsune, Roppongi Hills Mori Tower",
+ "Miku Hatsune, Roppongi Hills Mori Tower, 6-10-1 Roppongi",
+ "Miku Hatsune, Roppongi Hills Mori Tower, 6-10-1 Roppongi, Minato-ku",
+ "Miku Hatsune, Roppongi Hills Mori Tower, 6-10-1 Roppongi, Minato-ku, "
+ "Tokyo",
+ "Miku Hatsune, Roppongi Hills Mori Tower, 6-10-1 Roppongi, Minato-ku, "
+ "Tokyo, 106-6126",
+ "Miku Hatsune, Rei Inc, Roppongi Hills Mori Tower, 6-10-1 Roppongi, "
+ "Minato-ku, Tokyo, 106-6126",
+ "Miku Hatsune, Rei Inc, Roppongi Hills Mori Tower, 6-10-1 Roppongi, "
+ "Minato-ku, Tokyo, 106-6126, Japan",
+ "Miku Hatsune, Rei Inc, Roppongi Hills Mori Tower, 6-10-1 Roppongi, "
+ "Minato-ku, Tokyo, 106-6126, Japan, miku@rei.com",
+ "Miku Hatsune, Rei Inc, Roppongi Hills Mori Tower, 6-10-1 Roppongi, "
+ "Minato-ku, Tokyo, 106-6126, Japan, miku@rei.com, +81363849000",
+ };
+
+ std::vector<base::string16> labels;
+ for (size_t i = 0; i < arraysize(kExpectedLabels); ++i) {
+ AutofillProfile::CreateInferredLabels(
+ profiles.get(), NULL, UNKNOWN_TYPE, i, "en-US", &labels);
+ ASSERT_FALSE(labels.empty());
+ EXPECT_EQ(UTF8ToUTF16(kExpectedLabels[i]), labels.back());
+ }
+}
+
+TEST(AutofillProfileTest, CreateInferredLabelsI18n_JP_ja) {
+ ScopedVector<AutofillProfile> profiles;
+ profiles.push_back(
+ new AutofillProfile(base::GenerateGUID(), "https://www.example.com/"));
+ test::SetProfileInfo(profiles.back(),
+ "ミク",
+ "",
+ "初音",
+ "miku@rei.com",
+ "例",
+ "六本木ヒルズ森タワー",
+ "六本木 6-10-1",
+ "港区", "東京都",
+ "106-6126",
+ "JP",
+ "03-6384-9000");
+ profiles.back()->set_language_code("ja_JP");
+ static const char* kExpectedLabels[] = {
+ "",
+ "ミク 初音",
+ "六本木ヒルズ森タワーミク 初音",
+ "六本木ヒルズ森タワー六本木 6-10-1ミク 初音",
+ "港区六本木ヒルズ森タワー六本木 6-10-1ミク 初音",
+ "東京都港区六本木ヒルズ森タワー六本木 6-10-1ミク 初音",
+ "〒106-6126東京都港区六本木ヒルズ森タワー六本木 6-10-1ミク 初音",
+ "〒106-6126東京都港区六本木ヒルズ森タワー六本木 6-10-1例ミク 初音",
+ "〒106-6126東京都港区六本木ヒルズ森タワー六本木 6-10-1例ミク 初音, Japan",
+ "〒106-6126東京都港区六本木ヒルズ森タワー六本木 6-10-1例ミク 初音, Japan, "
+ "miku@rei.com",
+ "〒106-6126東京都港区六本木ヒルズ森タワー六本木 6-10-1例ミク 初音, Japan, "
+ "miku@rei.com, 0363849000",
+ };
+
+ std::vector<base::string16> labels;
+ for (size_t i = 0; i < arraysize(kExpectedLabels); ++i) {
+ AutofillProfile::CreateInferredLabels(
+ profiles.get(), NULL, UNKNOWN_TYPE, i, "en-US", &labels);
+ ASSERT_FALSE(labels.empty());
+ EXPECT_EQ(UTF8ToUTF16(kExpectedLabels[i]), labels.back());
+ }
+}
+
TEST(AutofillProfileTest, CreateInferredLabels) {
ScopedVector<AutofillProfile> profiles;
profiles.push_back(
std::vector<base::string16> labels;
// Two fields at least - no filter.
AutofillProfile::CreateInferredLabels(profiles.get(), NULL, UNKNOWN_TYPE, 2,
- &labels);
+ "en-US", &labels);
EXPECT_EQ(ASCIIToUTF16("John Doe, 666 Erebus St."), labels[0]);
EXPECT_EQ(ASCIIToUTF16("Jane Doe, 123 Letha Shore."), labels[1]);
// Three fields at least - no filter.
AutofillProfile::CreateInferredLabels(profiles.get(), NULL, UNKNOWN_TYPE, 3,
- &labels);
+ "en-US", &labels);
EXPECT_EQ(ASCIIToUTF16("John Doe, 666 Erebus St., Elysium"),
labels[0]);
EXPECT_EQ(ASCIIToUTF16("Jane Doe, 123 Letha Shore., Dis"),
// Two fields at least, from suggested fields - no filter.
AutofillProfile::CreateInferredLabels(profiles.get(), &suggested_fields,
- UNKNOWN_TYPE, 2, &labels);
+ UNKNOWN_TYPE, 2, "en-US", &labels);
EXPECT_EQ(ASCIIToUTF16("Elysium, CA"), labels[0]);
EXPECT_EQ(ASCIIToUTF16("Dis, CA"), labels[1]);
// Three fields at least, from suggested fields - no filter.
AutofillProfile::CreateInferredLabels(profiles.get(), &suggested_fields,
- UNKNOWN_TYPE, 3, &labels);
- EXPECT_EQ(ASCIIToUTF16("Elysium, CA, 91111"), labels[0]);
- EXPECT_EQ(ASCIIToUTF16("Dis, CA, 91222"), labels[1]);
+ UNKNOWN_TYPE, 3, "en-US", &labels);
+ EXPECT_EQ(ASCIIToUTF16("Elysium, CA 91111"), labels[0]);
+ EXPECT_EQ(ASCIIToUTF16("Dis, CA 91222"), labels[1]);
// Three fields at least, from suggested fields - but filter reduces available
// fields to two.
AutofillProfile::CreateInferredLabels(profiles.get(), &suggested_fields,
- ADDRESS_HOME_STATE, 3, &labels);
- EXPECT_EQ(ASCIIToUTF16("Elysium, 91111"), labels[0]);
- EXPECT_EQ(ASCIIToUTF16("Dis, 91222"), labels[1]);
+ ADDRESS_HOME_STATE, 3, "en-US",
+ &labels);
+ EXPECT_EQ(ASCIIToUTF16("Elysium 91111"), labels[0]);
+ EXPECT_EQ(ASCIIToUTF16("Dis 91222"), labels[1]);
suggested_fields.clear();
// In our implementation we always display NAME_FULL for all NAME* fields...
suggested_fields.push_back(NAME_MIDDLE);
// One field at least, from suggested fields - no filter.
AutofillProfile::CreateInferredLabels(profiles.get(), &suggested_fields,
- UNKNOWN_TYPE, 1, &labels);
+ UNKNOWN_TYPE, 1, "en-US", &labels);
EXPECT_EQ(ASCIIToUTF16("John Doe"), labels[0]);
EXPECT_EQ(ASCIIToUTF16("Jane Doe"), labels[1]);
// One field at least, from suggested fields - filter the same as suggested
// field.
AutofillProfile::CreateInferredLabels(profiles.get(), &suggested_fields,
- NAME_MIDDLE, 1, &labels);
+ NAME_MIDDLE, 1, "en-US", &labels);
EXPECT_EQ(base::string16(), labels[0]);
EXPECT_EQ(base::string16(), labels[1]);
suggested_fields.push_back(NAME_MIDDLE_INITIAL);
// One field at least, from suggested fields - no filter.
AutofillProfile::CreateInferredLabels(profiles.get(), &suggested_fields,
- UNKNOWN_TYPE, 1, &labels);
+ UNKNOWN_TYPE, 1, "en-US", &labels);
EXPECT_EQ(ASCIIToUTF16("John Doe"), labels[0]);
EXPECT_EQ(ASCIIToUTF16("Jane Doe"), labels[1]);
suggested_fields.push_back(NAME_FULL);
suggested_fields.push_back(ADDRESS_HOME_LINE1);
AutofillProfile::CreateInferredLabels(profiles.get(), &suggested_fields,
- NAME_FULL, 1, &labels);
+ NAME_FULL, 1, "en-US", &labels);
+ EXPECT_EQ(base::string16(ASCIIToUTF16("666 Erebus St.")), labels[0]);
+ EXPECT_EQ(base::string16(ASCIIToUTF16("123 Letha Shore.")), labels[1]);
+
+ // No suggested fields, but non-unknown excluded field.
+ AutofillProfile::CreateInferredLabels(profiles.get(), NULL,
+ NAME_FULL, 1, "en-US", &labels);
EXPECT_EQ(base::string16(ASCIIToUTF16("666 Erebus St.")), labels[0]);
EXPECT_EQ(base::string16(ASCIIToUTF16("123 Letha Shore.")), labels[1]);
}
suggested_fields.push_back(EMAIL_ADDRESS);
std::vector<base::string16> labels;
AutofillProfile::CreateInferredLabels(profiles.get(), &suggested_fields,
- NAME_LAST, 1, &labels);
+ NAME_LAST, 1, "en-US", &labels);
ASSERT_EQ(2U, labels.size());
EXPECT_EQ(ASCIIToUTF16("88 Nowhere Ave."), labels[0]);
EXPECT_EQ(ASCIIToUTF16("88 Nowhere Ave."), labels[1]);
// Otherwise, we should.
suggested_fields.push_back(NAME_FIRST);
AutofillProfile::CreateInferredLabels(profiles.get(), &suggested_fields,
- NAME_LAST, 1, &labels);
+ NAME_LAST, 1, "en-US", &labels);
ASSERT_EQ(2U, labels.size());
EXPECT_EQ(ASCIIToUTF16("88 Nowhere Ave., John Doe"), labels[0]);
EXPECT_EQ(ASCIIToUTF16("88 Nowhere Ave., Johnny K Doe"), labels[1]);
suggested_fields.push_back(EMAIL_ADDRESS);
std::vector<base::string16> labels;
AutofillProfile::CreateInferredLabels(profiles.get(), &suggested_fields,
- UNKNOWN_TYPE, 2, &labels);
+ UNKNOWN_TYPE, 2, "en-US", &labels);
ASSERT_EQ(2U, labels.size());
EXPECT_EQ(ASCIIToUTF16("88 Nowhere Ave., doe@example.com"), labels[0]);
EXPECT_EQ(ASCIIToUTF16("88 Nowhere Ave., dojo@example.com"), labels[1]);
std::vector<base::string16> labels;
AutofillProfile::CreateInferredLabels(profiles.get(), NULL, UNKNOWN_TYPE, 3,
- &labels);
+ "en-US", &labels);
ASSERT_EQ(3U, labels.size());
EXPECT_EQ(ASCIIToUTF16("John Doe, doe@example.com, Gogole"), labels[0]);
EXPECT_EQ(ASCIIToUTF16("John Doe, doe@example.com, Ggoole"), labels[1]);
// distinguishing field.
profiles[1]->SetRawInfo(ADDRESS_HOME_LINE1, ASCIIToUTF16("88 Nowhere Ave."));
AutofillProfile::CreateInferredLabels(profiles.get(), NULL, UNKNOWN_TYPE, 1,
- &labels);
+ "en-US", &labels);
ASSERT_EQ(3U, labels.size());
EXPECT_EQ(ASCIIToUTF16("John Doe, doe@example.com, Gogole"), labels[0]);
EXPECT_EQ(ASCIIToUTF16("John Doe, 88 Nowhere Ave., doe@example.com, Ggoole"),
suggested_fields.push_back(ADDRESS_HOME_STREET_ADDRESS);
std::vector<base::string16> labels;
AutofillProfile::CreateInferredLabels(profiles.get(), &suggested_fields,
- NAME_FULL, 1, &labels);
+ NAME_FULL, 1, "en-US", &labels);
ASSERT_EQ(1U, labels.size());
EXPECT_EQ(ASCIIToUTF16("88 Nowhere Ave., Apt. 42"), labels[0]);
}
"marion@me.xyz", "Fox", "123 Zoo St.", "unit 5",
"Hollywood", "CA", "91601", "US",
"12345678910");
- std::vector<base::string16> names;
- a.GetRawMultiInfo(NAME_FULL, &names);
- names.push_back(ASCIIToUTF16("Marion Morrison"));
- a.SetRawMultiInfo(NAME_FULL, names);
+ std::vector<base::string16> first_names;
+ a.GetRawMultiInfo(NAME_FIRST, &first_names);
+ first_names.push_back(ASCIIToUTF16("Marion"));
+ a.SetRawMultiInfo(NAME_FIRST, first_names);
+
+ std::vector<base::string16> last_names;
+ a.GetRawMultiInfo(NAME_LAST, &last_names);
+ last_names[last_names.size() - 1] = ASCIIToUTF16("Morrison");
+ a.SetRawMultiInfo(NAME_LAST, last_names);
// Create an identical profile except that the new profile:
// (1) Has a different origin,
// (2) Has a different address line 2,
- // (3) Lacks a company name, and
- // (4) Has a different full name variant.
+ // (3) Lacks a company name,
+ // (4) Has a different full name variant, and
+ // (5) Has a language code.
AutofillProfile b = a;
b.set_guid(base::GenerateGUID());
b.set_origin("Chrome settings");
b.SetRawInfo(ADDRESS_HOME_LINE2, ASCIIToUTF16("area 51"));
b.SetRawInfo(COMPANY_NAME, base::string16());
- b.GetRawMultiInfo(NAME_FULL, &names);
+
+ std::vector<base::string16> names;
+ b.GetMultiInfo(AutofillType(NAME_FULL), "en-US", &names);
names.push_back(ASCIIToUTF16("Marion M. Morrison"));
b.SetRawMultiInfo(NAME_FULL, names);
+ b.set_language_code("en");
a.OverwriteWithOrAddTo(b, "en-US");
EXPECT_EQ("Chrome settings", a.origin());
EXPECT_EQ(ASCIIToUTF16("area 51"), a.GetRawInfo(ADDRESS_HOME_LINE2));
EXPECT_EQ(ASCIIToUTF16("Fox"), a.GetRawInfo(COMPANY_NAME));
- a.GetRawMultiInfo(NAME_FULL, &names);
+ a.GetMultiInfo(AutofillType(NAME_FULL), "en-US", &names);
ASSERT_EQ(3U, names.size());
EXPECT_EQ(ASCIIToUTF16("Marion Mitchell Morrison"), names[0]);
EXPECT_EQ(ASCIIToUTF16("Marion Morrison"), names[1]);
EXPECT_EQ(ASCIIToUTF16("Marion M. Morrison"), names[2]);
+ EXPECT_EQ("en", a.language_code());
}
TEST(AutofillProfileTest, AssignmentOperator) {
EXPECT_TRUE(a == b);
}
+TEST(AutofillProfileTest, SetMultiInfo) {
+ std::vector<base::string16> full_names;
+ full_names.push_back(ASCIIToUTF16("John Davis"));
+ full_names.push_back(ASCIIToUTF16("Elouise Davis"));
+ AutofillProfile p;
+ p.SetMultiInfo(AutofillType(NAME_FULL), full_names, "en-US");
+
+ std::vector<base::string16> first_names;
+ p.GetMultiInfo(AutofillType(NAME_FIRST), "en-US", &first_names);
+ ASSERT_EQ(2U, first_names.size());
+ EXPECT_EQ(ASCIIToUTF16("John"), first_names[0]);
+ EXPECT_EQ(ASCIIToUTF16("Elouise"), first_names[1]);
+
+ std::vector<base::string16> last_names;
+ p.GetMultiInfo(AutofillType(NAME_LAST), "en-US", &last_names);
+ ASSERT_EQ(2U, last_names.size());
+ EXPECT_EQ(ASCIIToUTF16("Davis"), last_names[0]);
+ EXPECT_EQ(ASCIIToUTF16("Davis"), last_names[1]);
+}
+
TEST(AutofillProfileTest, Copy) {
AutofillProfile a(base::GenerateGUID(), "https://www.example.com/");
test::SetProfileInfo(&a, "Marion", "Mitchell", "Morrison",
NULL, NULL, NULL, NULL, NULL, NULL, NULL, "408.555.4321");
EXPECT_GT(0, a.Compare(b));
EXPECT_LT(0, b.Compare(a));
+
+ // Addresses are compared in full. Regression test for http://crbug.com/375545
+ test::SetProfileInfo(&a, "John", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+ a.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS,
+ ASCIIToUTF16("line one\nline two"));
+ test::SetProfileInfo(&b, "John", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+ b.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS,
+ ASCIIToUTF16("line one\nline two\nline three"));
+ EXPECT_GT(0, a.Compare(b));
+ EXPECT_LT(0, b.Compare(a));
}
TEST(AutofillProfileTest, MultiValueNames) {
profile.GetRawInfo(EMAIL_ADDRESS));
}
+TEST(AutofillProfileTest, FullAddress) {
+ AutofillProfile profile(base::GenerateGUID(), "https://www.example.com/");
+ test::SetProfileInfo(&profile, "Marion", "Mitchell", "Morrison",
+ "marion@me.xyz", "Fox", "123 Zoo St.", "unit 5",
+ "Hollywood", "CA", "91601", "US",
+ "12345678910");
+
+ AutofillType full_address(HTML_TYPE_FULL_ADDRESS, HTML_MODE_NONE);
+ base::string16 formatted_address(ASCIIToUTF16(
+ "Marion Mitchell Morrison\n"
+ "Fox\n"
+ "123 Zoo St.\n"
+ "unit 5\n"
+ "Hollywood, CA 91601"));
+ EXPECT_EQ(formatted_address, profile.GetInfo(full_address, "en-US"));
+ // This should fail and leave the profile unchanged.
+ EXPECT_FALSE(profile.SetInfo(full_address, ASCIIToUTF16("foobar"), "en-US"));
+ EXPECT_EQ(formatted_address, profile.GetInfo(full_address, "en-US"));
+
+ // Some things can be missing...
+ profile.SetInfo(AutofillType(ADDRESS_HOME_LINE2),
+ base::string16(),
+ "en-US");
+ profile.SetInfo(AutofillType(EMAIL_ADDRESS),
+ base::string16(),
+ "en-US");
+ EXPECT_EQ(ASCIIToUTF16("Marion Mitchell Morrison\n"
+ "Fox\n"
+ "123 Zoo St.\n"
+ "Hollywood, CA 91601"),
+ profile.GetInfo(full_address, "en-US"));
+
+ // ...but nothing comes out if a required field is missing.
+ profile.SetInfo(AutofillType(ADDRESS_HOME_STATE), base::string16(), "en-US");
+ EXPECT_TRUE(profile.GetInfo(full_address, "en-US").empty());
+
+ // Restore the state but remove country. This should also fail.
+ profile.SetInfo(AutofillType(ADDRESS_HOME_STATE),
+ ASCIIToUTF16("CA"),
+ "en-US");
+ EXPECT_FALSE(profile.GetInfo(full_address, "en-US").empty());
+ profile.SetInfo(AutofillType(ADDRESS_HOME_COUNTRY),
+ base::string16(),
+ "en-US");
+ EXPECT_TRUE(profile.GetInfo(full_address, "en-US").empty());
+}
+
+TEST(AutofillProfileTest, OverwriteOrAppendNames) {
+ std::vector<TestCase> test_cases;
+
+ // Identical name.
+ test_cases.push_back(TestCase(NameParts("Marion", "Mitchell", "Morrison"),
+ NameParts("Marion", "Mitchell", "Morrison"),
+ NameParts("Marion", "Mitchell", "Morrison")));
+ test_cases.push_back(TestCase(NameParts("Marion", "Mitchell", "Morrison"),
+ NameParts("MARION", "MITCHELL", "MORRISON"),
+ NameParts("Marion", "Mitchell", "Morrison")));
+
+ // A parse that has a two-word last name should take precedence over a
+ // parse that assumes the two names are a middle and a last name.
+ test_cases.push_back(TestCase(NameParts("Marion", "Mitchell", "Morrison"),
+ NameParts("Marion", "", "Mitchell Morrison"),
+ NameParts("Marion", "", "Mitchell Morrison")));
+ test_cases.push_back(TestCase(NameParts("Marion", "", "Mitchell Morrison"),
+ NameParts("Marion", "Mitchell", "Morrison"),
+ NameParts("Marion", "", "Mitchell Morrison")));
+
+ // A parse that has a two-word first name should take precedence over a
+ // parse that assumes the two names are a first and a middle name.
+ test_cases.push_back(TestCase(NameParts("Marion", "Mitchell", "Morrison"),
+ NameParts("Marion Mitchell", "", "Morrison"),
+ NameParts("Marion Mitchell", "", "Morrison")));
+ test_cases.push_back(TestCase(NameParts("Marion Mitchell", "", "Morrison"),
+ NameParts("Marion", "Mitchell", "Morrison"),
+ NameParts("Marion Mitchell", "", "Morrison")));
+
+ // Two names that are identical in full, but not in parts: the parse that
+ // does *not* match the heuristic parse should be preferred.
+ test_cases.push_back(
+ TestCase(NameParts("Arthur", "Ignatius Conan", "Doyle"),
+ // Heurstic parse.
+ NameParts("Arthur Ignatius", "Conan", "Doyle"),
+ NameParts("Arthur", "Ignatius Conan", "Doyle")));
+ test_cases.push_back(
+ // Heuristic parse.
+ TestCase(NameParts("Arthur Ignatius", "Conan", "Doyle"),
+ NameParts("Arthur", "Ignatius Conan", "Doyle"),
+ NameParts("Arthur", "Ignatius Conan", "Doyle")));
+
+ // A parse that has a many-word first name and/or last name should take
+ // precedence over a heuristically parsed name.
+ test_cases.push_back(
+ // Heuristic parse.
+ TestCase(NameParts("Roberto Carlos da", "Silva", "Rocha"),
+ NameParts("Roberto Carlos da Silva", "", "Rocha"),
+ NameParts("Roberto Carlos da Silva", "", "Rocha")));
+
+ // Cases where merging 2 profiles with same full names but
+ // different canonical forms appends instead of overwrites,
+ // provided they dont form heuristically parsed names.
+ {
+ NameParts name1("Marion Mitchell", "", "Morrison");
+ NameParts name2("Marion", "", "Mitchell Morrison");
+ std::vector<NameParts> starting_names(1, name1);
+ std::vector<NameParts> additional_names(1, name2);
+ std::vector<NameParts> expected_result;
+ expected_result.push_back(name1);
+ expected_result.push_back(name2);
+ test_cases.push_back(
+ TestCase(starting_names, additional_names, expected_result));
+ }
+
+ // Cases where the names do not have the same full name strings,
+ // i.e. the list of merged names is longer than either of the incoming
+ // lists.
+ {
+ NameParts name1("Antonio", "Augusto Ribeiro", "Reis Jr.");
+ NameParts name2("Juninho", "", "Pernambucano");
+ NameParts name3("Marion", "Mitchell", "Morrison");
+ NameParts name4("Marion", "M.", "Morrison");
+ std::vector<NameParts> starting_names;
+ std::vector<NameParts> additional_names;
+ std::vector<NameParts> expected_result;
+ starting_names.push_back(name1);
+ starting_names.push_back(name2);
+ additional_names.push_back(name3);
+ additional_names.push_back(name4);
+ expected_result.push_back(name1);
+ expected_result.push_back(name2);
+ expected_result.push_back(name3);
+ expected_result.push_back(name4);
+ test_cases.push_back(
+ TestCase(starting_names, additional_names, expected_result));
+ }
+
+ for (std::vector<TestCase>::iterator it = test_cases.begin();
+ it != test_cases.end();
+ ++it) {
+ TestCase current_case = *it;
+ SCOPED_TRACE(current_case.starting_names[0].first + " + " +
+ current_case.additional_names[0].first + " = " +
+ current_case.expected_result[0].first);
+
+ std::vector<base::string16> first_names, middle_names, last_names;
+ GetNamePartsList(
+ current_case.starting_names, &first_names, &middle_names, &last_names);
+
+ // Construct the starting_profile.
+ AutofillProfile starting_profile(base::GenerateGUID(),
+ "https://www.example.com/");
+
+ starting_profile.SetRawMultiInfo(NAME_FIRST, first_names);
+ starting_profile.SetRawMultiInfo(NAME_MIDDLE, middle_names);
+ starting_profile.SetRawMultiInfo(NAME_LAST, last_names);
+
+ first_names.clear();
+ middle_names.clear();
+ last_names.clear();
+ GetNamePartsList(
+ current_case.additional_names, &first_names, &middle_names,
+ &last_names);
+
+ // Construct the additional_profile.
+ AutofillProfile additional_profile(base::GenerateGUID(),
+ "https://www.example.com/");
+ additional_profile.SetRawMultiInfo(NAME_FIRST, first_names);
+ additional_profile.SetRawMultiInfo(NAME_MIDDLE, middle_names);
+ additional_profile.SetRawMultiInfo(NAME_LAST, last_names);
+
+ // Merge the names from the |additional_profile| into the |starting_profile|
+ starting_profile.OverwriteWithOrAddTo(additional_profile, "en-US");
+
+ // Verify the test expectations.
+ first_names.clear();
+ middle_names.clear();
+ last_names.clear();
+ GetNamePartsList(
+ current_case.expected_result, &first_names, &middle_names, &last_names);
+
+ std::vector<base::string16> merged_first_names, merged_middle_names,
+ merged_last_names;
+ starting_profile.GetRawMultiInfo(NAME_FIRST, &merged_first_names);
+ starting_profile.GetRawMultiInfo(NAME_MIDDLE, &merged_middle_names);
+ starting_profile.GetRawMultiInfo(NAME_LAST, &merged_last_names);
+ ASSERT_EQ(current_case.expected_result.size(), merged_first_names.size());
+ ASSERT_EQ(current_case.expected_result.size(), merged_middle_names.size());
+ ASSERT_EQ(current_case.expected_result.size(), merged_last_names.size());
+
+ for (size_t i = 0; i < current_case.expected_result.size(); ++i) {
+ EXPECT_EQ(first_names[i], merged_first_names[i]);
+ EXPECT_EQ(middle_names[i], merged_middle_names[i]);
+ EXPECT_EQ(last_names[i], merged_last_names[i]);
+ }
+ }
+}
+
} // namespace autofill