Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/basictypes.h" | 5 #include "base/basictypes.h" |
| 6 #include "base/format_macros.h" | |
| 6 #include "base/guid.h" | 7 #include "base/guid.h" |
| 7 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
| 8 #include "base/memory/scoped_vector.h" | 9 #include "base/memory/scoped_vector.h" |
| 9 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
| 10 #include "base/strings/string16.h" | 11 #include "base/strings/string16.h" |
| 12 #include "base/strings/stringprintf.h" | |
| 11 #include "base/strings/utf_string_conversions.h" | 13 #include "base/strings/utf_string_conversions.h" |
| 12 #include "components/autofill/core/browser/autofill_profile.h" | 14 #include "components/autofill/core/browser/autofill_profile.h" |
| 13 #include "components/autofill/core/browser/autofill_test_utils.h" | 15 #include "components/autofill/core/browser/autofill_test_utils.h" |
| 14 #include "components/autofill/core/browser/autofill_type.h" | 16 #include "components/autofill/core/browser/autofill_type.h" |
| 17 #include "components/autofill/core/browser/field_types.h" | |
| 15 #include "components/autofill/core/common/form_field_data.h" | 18 #include "components/autofill/core/common/form_field_data.h" |
| 16 #include "grit/components_strings.h" | 19 #include "grit/components_strings.h" |
| 17 #include "testing/gtest/include/gtest/gtest.h" | 20 #include "testing/gtest/include/gtest/gtest.h" |
| 18 | 21 |
| 19 using base::ASCIIToUTF16; | 22 using base::ASCIIToUTF16; |
| 20 | 23 |
| 21 namespace autofill { | 24 namespace autofill { |
| 22 | 25 |
| 23 namespace { | 26 namespace { |
| 24 | 27 |
| 25 base::string16 GetLabel(AutofillProfile* profile) { | 28 base::string16 GetLabel(AutofillProfile* profile) { |
| 26 std::vector<AutofillProfile*> profiles; | 29 std::vector<AutofillProfile*> profiles; |
| 27 profiles.push_back(profile); | 30 profiles.push_back(profile); |
| 28 std::vector<base::string16> labels; | 31 std::vector<base::string16> labels; |
| 29 AutofillProfile::CreateDifferentiatingLabels(profiles, &labels); | 32 AutofillProfile::CreateDifferentiatingLabels(profiles, &labels); |
| 30 return labels[0]; | 33 return labels[0]; |
| 31 } | 34 } |
| 32 | 35 |
| 36 // Holds the autofill profile |first|, |middle| and |last| names. | |
| 37 struct NameParts { | |
| 38 NameParts(const std::string& first, | |
| 39 const std::string& middle, | |
| 40 const std::string& last) | |
| 41 : first(first), middle(middle), last(last) {} | |
| 42 | |
| 43 std::string first; | |
| 44 std::string middle; | |
| 45 std::string last; | |
| 46 }; | |
| 47 | |
| 48 // Test case to be executed to validate OverwriteOrAppendNames. | |
| 49 struct TestCase { | |
| 50 TestCase(const NameParts& starting_name, | |
| 51 const NameParts& additional_name, | |
| 52 const NameParts& expected_result) | |
| 53 : starting_names(std::vector<NameParts>(1, starting_name)), | |
| 54 additional_names(std::vector<NameParts>(1, additional_name)), | |
| 55 expected_result(std::vector<NameParts>(1, expected_result)) {} | |
| 56 | |
| 57 TestCase(const std::vector<NameParts>& starting_names, | |
| 58 const std::vector<NameParts>& additional_names, | |
| 59 const std::vector<NameParts>& expected_result) | |
| 60 : starting_names(starting_names), | |
| 61 additional_names(additional_names), | |
| 62 expected_result(expected_result) {} | |
| 63 | |
| 64 std::vector<NameParts> starting_names; | |
| 65 std::vector<NameParts> additional_names; | |
| 66 std::vector<NameParts> expected_result; | |
| 67 }; | |
| 68 | |
| 69 // Populates |first_names|, |middle_names| and |last_names| from the list of | |
| 70 // NameParts from |starting_names|, |additional_names| or |expected_result| | |
| 71 // from the testcase to create and verify the autofill profile. | |
| 72 void GetNamePartsList(const std::vector<NameParts>& names, | |
| 73 std::vector<base::string16>& first_names, | |
| 74 std::vector<base::string16>& middle_names, | |
| 75 std::vector<base::string16>& last_names) { | |
| 76 for (size_t i = 0; i < names.size(); ++i) { | |
| 77 first_names.push_back(ASCIIToUTF16(names[i].first)); | |
| 78 middle_names.push_back(ASCIIToUTF16(names[i].middle)); | |
| 79 last_names.push_back(ASCIIToUTF16(names[i].last)); | |
| 80 } | |
| 81 } | |
| 82 | |
| 33 } // namespace | 83 } // namespace |
| 34 | 84 |
| 35 // Tests different possibilities for summary string generation. | 85 // Tests different possibilities for summary string generation. |
| 36 // Based on existence of first name, last name, and address line 1. | 86 // Based on existence of first name, last name, and address line 1. |
| 37 TEST(AutofillProfileTest, PreviewSummaryString) { | 87 TEST(AutofillProfileTest, PreviewSummaryString) { |
| 38 // Case 0/null: "" | 88 // Case 0/null: "" |
| 39 AutofillProfile profile0(base::GenerateGUID(), "https://www.example.com/"); | 89 AutofillProfile profile0(base::GenerateGUID(), "https://www.example.com/"); |
| 40 // Empty profile - nothing to update. | 90 // Empty profile - nothing to update. |
| 41 base::string16 summary0 = GetLabel(&profile0); | 91 base::string16 summary0 = GetLabel(&profile0); |
| 42 EXPECT_EQ(base::string16(), summary0); | 92 EXPECT_EQ(base::string16(), summary0); |
| (...skipping 848 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 891 profile.SetInfo(AutofillType(ADDRESS_HOME_STATE), | 941 profile.SetInfo(AutofillType(ADDRESS_HOME_STATE), |
| 892 ASCIIToUTF16("CA"), | 942 ASCIIToUTF16("CA"), |
| 893 "en-US"); | 943 "en-US"); |
| 894 EXPECT_FALSE(profile.GetInfo(full_address, "en-US").empty()); | 944 EXPECT_FALSE(profile.GetInfo(full_address, "en-US").empty()); |
| 895 profile.SetInfo(AutofillType(ADDRESS_HOME_COUNTRY), | 945 profile.SetInfo(AutofillType(ADDRESS_HOME_COUNTRY), |
| 896 base::string16(), | 946 base::string16(), |
| 897 "en-US"); | 947 "en-US"); |
| 898 EXPECT_TRUE(profile.GetInfo(full_address, "en-US").empty()); | 948 EXPECT_TRUE(profile.GetInfo(full_address, "en-US").empty()); |
| 899 } | 949 } |
| 900 | 950 |
| 951 TEST(AutofillProfileTest, OverwriteOrAppendNames) { | |
| 952 std::vector<TestCase> test_cases; | |
| 953 | |
| 954 // Identical name. | |
| 955 test_cases.push_back(TestCase(NameParts("Marion", "Mitchell", "Morrison"), | |
| 956 NameParts("Marion", "Mitchell", "Morrison"), | |
| 957 NameParts("Marion", "Mitchell", "Morrison"))); | |
| 958 | |
| 959 // A parse that has a two-word last name should take precedence over a | |
| 960 // parse that assumes the two names are a middle and a last name. | |
| 961 test_cases.push_back(TestCase(NameParts("Marion", "Mitchell", "Morrison"), | |
| 962 NameParts("Marion", "", "Mitchell Morrison"), | |
| 963 NameParts("Marion", "", "Mitchell Morrison"))); | |
| 964 test_cases.push_back(TestCase(NameParts("Marion", "", "Mitchell Morrison"), | |
| 965 NameParts("Marion", "Mitchell", "Morrison"), | |
| 966 NameParts("Marion", "", "Mitchell Morrison"))); | |
| 967 | |
| 968 // A parse that has a two-word first name should take precedence over a | |
| 969 // parse that assumes the two names are a first and a middle name. | |
| 970 test_cases.push_back(TestCase(NameParts("Marion", "Mitchell", "Morrison"), | |
| 971 NameParts("Marion Mitchell", "", "Morrison"), | |
| 972 NameParts("Marion Mitchell", "", "Morrison"))); | |
| 973 test_cases.push_back(TestCase(NameParts("Marion Mitchell", "", "Morrison"), | |
| 974 NameParts("Marion", "Mitchell", "Morrison"), | |
| 975 NameParts("Marion Mitchell", "", "Morrison"))); | |
| 976 | |
| 977 // A parse that has a two-word first name and two-word last name should | |
| 978 // take precedence over a parse that assumes the two middle names and | |
| 979 // one last name. | |
| 980 test_cases.push_back( | |
| 981 TestCase(NameParts("Arthur", "Ignatius Conan", "Doyle"), | |
| 982 NameParts("Arthur Ignatius", "", "Conan Doyle"), | |
| 983 NameParts("Arthur Ignatius", "", "Conan Doyle"))); | |
| 984 test_cases.push_back( | |
| 985 TestCase(NameParts("Arthur Ignatius", "", "Conan Doyle"), | |
| 986 NameParts("Arthur", "Ignatius Conan", "Doyle"), | |
| 987 NameParts("Arthur Ignatius", "", "Conan Doyle"))); | |
| 988 | |
| 989 // A parse that has a many-word first name and/or last name should take | |
| 990 // precedence over a heuristically parsed name into {first, middle1 | |
| 991 // middle2.. middlen, name}. | |
| 992 test_cases.push_back( | |
| 993 TestCase(NameParts("Arthur Ignatius Conan", "", "Doyle"), | |
| 994 NameParts("Arthur", "Ignatius Conan", "Doyle"), | |
| 995 NameParts("Arthur Ignatius Conan", "", "Doyle"))); | |
| 996 test_cases.push_back( | |
| 997 TestCase(NameParts("Roberto", "Carlos da Silva", "Rocha"), | |
| 998 NameParts("Roberto Carlos da Silva", "", "Rocha"), | |
| 999 NameParts("Roberto Carlos da Silva", "", "Rocha"))); | |
| 1000 test_cases.push_back( | |
| 1001 TestCase(NameParts("Antonio", "Augusto", "Ribeiro Reis Jr."), | |
| 1002 NameParts("Antonio", "Augusto Ribeiro Reis", "Jr."), | |
| 1003 NameParts("Antonio", "Augusto", "Ribeiro Reis Jr."))); | |
| 1004 | |
| 1005 // Cases where merging 2 profiles with same fullnames but | |
|
Ilya Sherman
2014/06/09 22:11:52
nit: "fullnames" -> "full names"
Pritam Nikam
2014/06/11 04:11:42
Done.
| |
| 1006 // different canonical forms appends instead of overwrites, | |
| 1007 // provided they dont form heuristically parsed names. | |
| 1008 { | |
| 1009 NameParts name1("Marion Mitchell", "", "Morrison"); | |
| 1010 NameParts name2("Marion", "", "Mitchell Morrison"); | |
| 1011 std::vector<NameParts> starting_names(1, name1); | |
| 1012 std::vector<NameParts> additional_names(1, name2); | |
| 1013 std::vector<NameParts> expected_result; | |
| 1014 expected_result.push_back(name1); | |
| 1015 expected_result.push_back(name2); | |
| 1016 test_cases.push_back( | |
| 1017 TestCase(starting_names, additional_names, expected_result)); | |
| 1018 } | |
| 1019 | |
| 1020 // Cases where the names do not have the same full name strings, | |
| 1021 // i.e. the list of merged names is longer than either of the incoming | |
| 1022 // lists. | |
| 1023 { | |
| 1024 NameParts name1("Antonio", "Augusto Ribeiro", "Reis Jr."); | |
| 1025 NameParts name2("Juninho", "", "Pernambucano"); | |
| 1026 NameParts name3("Marion", "Mitchell", "Morrison"); | |
| 1027 NameParts name4("Marion", "M.", "Morrison"); | |
| 1028 std::vector<NameParts> starting_names; | |
| 1029 std::vector<NameParts> additional_names; | |
| 1030 std::vector<NameParts> expected_result; | |
| 1031 starting_names.push_back(name1); | |
| 1032 starting_names.push_back(name2); | |
| 1033 additional_names.push_back(name3); | |
| 1034 additional_names.push_back(name4); | |
| 1035 expected_result.push_back(name1); | |
| 1036 expected_result.push_back(name2); | |
| 1037 expected_result.push_back(name3); | |
| 1038 expected_result.push_back(name4); | |
| 1039 test_cases.push_back( | |
| 1040 TestCase(starting_names, additional_names, expected_result)); | |
| 1041 } | |
| 1042 | |
| 1043 for (std::vector<TestCase>::iterator it = test_cases.begin(); | |
| 1044 it != test_cases.end(); | |
| 1045 ++it) { | |
| 1046 TestCase current_case = *it; | |
| 1047 | |
| 1048 std::vector<base::string16> first_names, middle_names, last_names; | |
| 1049 GetNamePartsList( | |
| 1050 current_case.starting_names, first_names, middle_names, last_names); | |
| 1051 | |
| 1052 // Construct the starting_profile. | |
| 1053 AutofillProfile starting_profile(base::GenerateGUID(), | |
| 1054 "https://www.example.com/"); | |
| 1055 | |
| 1056 starting_profile.SetRawMultiInfo(NAME_FIRST, first_names); | |
| 1057 starting_profile.SetRawMultiInfo(NAME_MIDDLE, middle_names); | |
| 1058 starting_profile.SetRawMultiInfo(NAME_LAST, last_names); | |
| 1059 | |
| 1060 first_names.clear(); | |
| 1061 middle_names.clear(); | |
| 1062 last_names.clear(); | |
| 1063 GetNamePartsList( | |
| 1064 current_case.additional_names, first_names, middle_names, last_names); | |
| 1065 | |
| 1066 // Construct the additional_profile. | |
| 1067 AutofillProfile additional_profile(base::GenerateGUID(), | |
| 1068 "https://www.example.com/"); | |
| 1069 additional_profile.SetRawMultiInfo(NAME_FIRST, first_names); | |
| 1070 additional_profile.SetRawMultiInfo(NAME_MIDDLE, middle_names); | |
| 1071 additional_profile.SetRawMultiInfo(NAME_LAST, last_names); | |
| 1072 | |
| 1073 // Merge the names from the |additional_profile| into the |starting_profile| | |
| 1074 starting_profile.OverwriteWithOrAddTo(additional_profile, "en-US"); | |
| 1075 | |
| 1076 // Verify the test expectations. | |
| 1077 first_names.clear(); | |
| 1078 middle_names.clear(); | |
| 1079 last_names.clear(); | |
| 1080 GetNamePartsList( | |
| 1081 current_case.expected_result, first_names, middle_names, last_names); | |
| 1082 | |
| 1083 std::vector<base::string16> merged_first_names, merged_middle_names, | |
| 1084 merged_last_names; | |
| 1085 starting_profile.GetRawMultiInfo(NAME_FIRST, &merged_first_names); | |
| 1086 starting_profile.GetRawMultiInfo(NAME_MIDDLE, &merged_middle_names); | |
| 1087 starting_profile.GetRawMultiInfo(NAME_LAST, &merged_last_names); | |
| 1088 ASSERT_EQ(current_case.expected_result.size(), merged_first_names.size()); | |
| 1089 ASSERT_EQ(current_case.expected_result.size(), merged_middle_names.size()); | |
| 1090 ASSERT_EQ(current_case.expected_result.size(), merged_last_names.size()); | |
| 1091 | |
| 1092 for (size_t i = 0; i < current_case.expected_result.size(); ++i) { | |
| 1093 EXPECT_EQ(first_names[i], merged_first_names[i]); | |
| 1094 EXPECT_EQ(middle_names[i], merged_middle_names[i]); | |
| 1095 EXPECT_EQ(last_names[i], merged_last_names[i]); | |
| 1096 } | |
| 1097 } | |
| 1098 } | |
| 1099 | |
| 901 } // namespace autofill | 1100 } // namespace autofill |
| OLD | NEW |