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
3// found in the LICENSE file.
4
5#include "components/autofill/core/browser/contact_info.h"
6
7#include "base/basictypes.h"
8#include "base/format_macros.h"
9#include "base/strings/string_util.h"
10#include "base/strings/stringprintf.h"
11#include "base/strings/utf_string_conversions.h"
12#include "components/autofill/core/browser/autofill_type.h"
13#include "components/autofill/core/browser/field_types.h"
14#include "testing/gtest/include/gtest/gtest.h"
15
16using base::ASCIIToUTF16;
17
18namespace autofill {
19
20struct FullNameTestCase {
21  std::string full_name_input;
22  std::string given_name_output;
23  std::string middle_name_output;
24  std::string family_name_output;
25} full_name_test_cases[] = {
26  { "", "", "", "" },
27  { "John Smith", "John", "", "Smith" },
28  { "Julien van der Poel", "Julien", "", "van der Poel" },
29  { "John J Johnson", "John", "J", "Johnson" },
30  { "John Smith, Jr.", "John", "", "Smith" },
31  { "Mr John Smith", "John", "", "Smith" },
32  { "Mr. John Smith", "John", "", "Smith" },
33  { "Mr. John Smith, M.D.", "John", "", "Smith" },
34  { "Mr. John Smith, MD", "John", "", "Smith" },
35  { "Mr. John Smith MD", "John", "", "Smith" },
36  { "William Hubert J.R.", "William", "Hubert", "J.R." },
37  { "John Ma", "John", "", "Ma" },
38  { "John Smith, MA", "John", "", "Smith" },
39  { "John Jacob Jingleheimer Smith", "John Jacob", "Jingleheimer", "Smith" },
40  { "Virgil", "Virgil", "", "" },
41  { "Murray Gell-Mann", "Murray", "", "Gell-Mann" },
42  { "Mikhail Yevgrafovich Saltykov-Shchedrin", "Mikhail", "Yevgrafovich",
43    "Saltykov-Shchedrin" },
44  { "Arthur Ignatius Conan Doyle", "Arthur Ignatius", "Conan", "Doyle" },
45};
46
47TEST(NameInfoTest, SetFullName) {
48  for (size_t i = 0; i < arraysize(full_name_test_cases); ++i) {
49    const FullNameTestCase& test_case = full_name_test_cases[i];
50    SCOPED_TRACE(test_case.full_name_input);
51
52    NameInfo name;
53    name.SetInfo(AutofillType(NAME_FULL),
54                 ASCIIToUTF16(test_case.full_name_input),
55                 "en-US");
56    EXPECT_EQ(ASCIIToUTF16(test_case.given_name_output),
57              name.GetInfo(AutofillType(NAME_FIRST), "en-US"));
58    EXPECT_EQ(ASCIIToUTF16(test_case.middle_name_output),
59              name.GetInfo(AutofillType(NAME_MIDDLE), "en-US"));
60    EXPECT_EQ(ASCIIToUTF16(test_case.family_name_output),
61              name.GetInfo(AutofillType(NAME_LAST), "en-US"));
62    EXPECT_EQ(ASCIIToUTF16(test_case.full_name_input),
63              name.GetInfo(AutofillType(NAME_FULL), "en-US"));
64  }
65}
66
67TEST(NameInfoTest, GetFullName) {
68  NameInfo name;
69  name.SetRawInfo(NAME_FIRST, ASCIIToUTF16("First"));
70  name.SetRawInfo(NAME_MIDDLE, base::string16());
71  name.SetRawInfo(NAME_LAST, base::string16());
72  EXPECT_EQ(ASCIIToUTF16("First"), name.GetRawInfo(NAME_FIRST));
73  EXPECT_EQ(base::string16(), name.GetRawInfo(NAME_MIDDLE));
74  EXPECT_EQ(base::string16(), name.GetRawInfo(NAME_LAST));
75  EXPECT_EQ(base::string16(), name.GetRawInfo(NAME_FULL));
76  EXPECT_EQ(ASCIIToUTF16("First"),
77            name.GetInfo(AutofillType(NAME_FULL), "en-US"));
78
79  name.SetRawInfo(NAME_FIRST, base::string16());
80  name.SetRawInfo(NAME_MIDDLE, ASCIIToUTF16("Middle"));
81  name.SetRawInfo(NAME_LAST, base::string16());
82  EXPECT_EQ(base::string16(), name.GetRawInfo(NAME_FIRST));
83  EXPECT_EQ(ASCIIToUTF16("Middle"), name.GetRawInfo(NAME_MIDDLE));
84  EXPECT_EQ(base::string16(), name.GetRawInfo(NAME_LAST));
85  EXPECT_EQ(base::string16(), name.GetRawInfo(NAME_FULL));
86  EXPECT_EQ(ASCIIToUTF16("Middle"),
87            name.GetInfo(AutofillType(NAME_FULL), "en-US"));
88
89  name.SetRawInfo(NAME_FIRST, base::string16());
90  name.SetRawInfo(NAME_MIDDLE, base::string16());
91  name.SetRawInfo(NAME_LAST, ASCIIToUTF16("Last"));
92  EXPECT_EQ(base::string16(), name.GetRawInfo(NAME_FIRST));
93  EXPECT_EQ(base::string16(), name.GetRawInfo(NAME_MIDDLE));
94  EXPECT_EQ(ASCIIToUTF16("Last"), name.GetRawInfo(NAME_LAST));
95  EXPECT_EQ(base::string16(), name.GetRawInfo(NAME_FULL));
96  EXPECT_EQ(ASCIIToUTF16("Last"),
97            name.GetInfo(AutofillType(NAME_FULL), "en-US"));
98
99  name.SetRawInfo(NAME_FIRST, ASCIIToUTF16("First"));
100  name.SetRawInfo(NAME_MIDDLE, ASCIIToUTF16("Middle"));
101  name.SetRawInfo(NAME_LAST, base::string16());
102  EXPECT_EQ(ASCIIToUTF16("First"), name.GetRawInfo(NAME_FIRST));
103  EXPECT_EQ(ASCIIToUTF16("Middle"), name.GetRawInfo(NAME_MIDDLE));
104  EXPECT_EQ(base::string16(), name.GetRawInfo(NAME_LAST));
105  EXPECT_EQ(base::string16(), name.GetRawInfo(NAME_FULL));
106  EXPECT_EQ(ASCIIToUTF16("First Middle"),
107            name.GetInfo(AutofillType(NAME_FULL), "en-US"));
108
109  name.SetRawInfo(NAME_FIRST, ASCIIToUTF16("First"));
110  name.SetRawInfo(NAME_MIDDLE, base::string16());
111  name.SetRawInfo(NAME_LAST, ASCIIToUTF16("Last"));
112  EXPECT_EQ(ASCIIToUTF16("First"), name.GetRawInfo(NAME_FIRST));
113  EXPECT_EQ(base::string16(), name.GetRawInfo(NAME_MIDDLE));
114  EXPECT_EQ(ASCIIToUTF16("Last"), name.GetRawInfo(NAME_LAST));
115  EXPECT_EQ(base::string16(), name.GetRawInfo(NAME_FULL));
116  EXPECT_EQ(ASCIIToUTF16("First Last"),
117            name.GetInfo(AutofillType(NAME_FULL), "en-US"));
118
119  name.SetRawInfo(NAME_FIRST, base::string16());
120  name.SetRawInfo(NAME_MIDDLE, ASCIIToUTF16("Middle"));
121  name.SetRawInfo(NAME_LAST, ASCIIToUTF16("Last"));
122  EXPECT_EQ(base::string16(), name.GetRawInfo(NAME_FIRST));
123  EXPECT_EQ(ASCIIToUTF16("Middle"), name.GetRawInfo(NAME_MIDDLE));
124  EXPECT_EQ(ASCIIToUTF16("Last"), name.GetRawInfo(NAME_LAST));
125  EXPECT_EQ(base::string16(), name.GetRawInfo(NAME_FULL));
126  EXPECT_EQ(ASCIIToUTF16("Middle Last"),
127            name.GetInfo(AutofillType(NAME_FULL), "en-US"));
128
129  name.SetRawInfo(NAME_FIRST, ASCIIToUTF16("First"));
130  name.SetRawInfo(NAME_MIDDLE, ASCIIToUTF16("Middle"));
131  name.SetRawInfo(NAME_LAST, ASCIIToUTF16("Last"));
132  EXPECT_EQ(ASCIIToUTF16("First"), name.GetRawInfo(NAME_FIRST));
133  EXPECT_EQ(ASCIIToUTF16("Middle"), name.GetRawInfo(NAME_MIDDLE));
134  EXPECT_EQ(ASCIIToUTF16("Last"), name.GetRawInfo(NAME_LAST));
135  EXPECT_EQ(base::string16(), name.GetRawInfo(NAME_FULL));
136  EXPECT_EQ(ASCIIToUTF16("First Middle Last"),
137            name.GetInfo(AutofillType(NAME_FULL), "en-US"));
138
139  name.SetRawInfo(NAME_FULL, ASCIIToUTF16("First Middle Last, MD"));
140  EXPECT_EQ(name.GetRawInfo(NAME_FIRST), ASCIIToUTF16("First"));
141  EXPECT_EQ(name.GetRawInfo(NAME_MIDDLE), ASCIIToUTF16("Middle"));
142  EXPECT_EQ(name.GetRawInfo(NAME_LAST), ASCIIToUTF16("Last"));
143  EXPECT_EQ(name.GetRawInfo(NAME_FULL), ASCIIToUTF16("First Middle Last, MD"));
144  EXPECT_EQ(ASCIIToUTF16("First Middle Last, MD"),
145            name.GetInfo(AutofillType(NAME_FULL), "en-US"));
146
147  // Setting a name to the value it already has: no change.
148  name.SetInfo(AutofillType(NAME_FIRST), ASCIIToUTF16("First"), "en-US");
149  EXPECT_EQ(name.GetRawInfo(NAME_FIRST), ASCIIToUTF16("First"));
150  EXPECT_EQ(name.GetRawInfo(NAME_MIDDLE), ASCIIToUTF16("Middle"));
151  EXPECT_EQ(name.GetRawInfo(NAME_LAST), ASCIIToUTF16("Last"));
152  EXPECT_EQ(name.GetRawInfo(NAME_FULL), ASCIIToUTF16("First Middle Last, MD"));
153  EXPECT_EQ(ASCIIToUTF16("First Middle Last, MD"),
154            name.GetInfo(AutofillType(NAME_FULL), "en-US"));
155
156  // Setting raw info: no change. (Even though this leads to a slightly
157  // inconsitent state.)
158  name.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Second"));
159  EXPECT_EQ(name.GetRawInfo(NAME_FIRST), ASCIIToUTF16("Second"));
160  EXPECT_EQ(name.GetRawInfo(NAME_MIDDLE), ASCIIToUTF16("Middle"));
161  EXPECT_EQ(name.GetRawInfo(NAME_LAST), ASCIIToUTF16("Last"));
162  EXPECT_EQ(name.GetRawInfo(NAME_FULL), ASCIIToUTF16("First Middle Last, MD"));
163  EXPECT_EQ(ASCIIToUTF16("First Middle Last, MD"),
164            name.GetInfo(AutofillType(NAME_FULL), "en-US"));
165
166  // Changing something (e.g., the first name) clears the stored full name.
167  name.SetInfo(AutofillType(NAME_FIRST), ASCIIToUTF16("Third"), "en-US");
168  EXPECT_EQ(name.GetRawInfo(NAME_FIRST), ASCIIToUTF16("Third"));
169  EXPECT_EQ(name.GetRawInfo(NAME_MIDDLE), ASCIIToUTF16("Middle"));
170  EXPECT_EQ(name.GetRawInfo(NAME_LAST), ASCIIToUTF16("Last"));
171  EXPECT_EQ(ASCIIToUTF16("Third Middle Last"),
172            name.GetInfo(AutofillType(NAME_FULL), "en-US"));
173}
174
175TEST(NameInfoTest, ParsedNamesAreEqual) {
176  struct TestCase {
177    std::string starting_names[3];
178    std::string additional_names[3];
179    bool expected_result;
180  };
181
182  struct TestCase test_cases[] = {
183      // Identical name comparison.
184      {{"Marion", "Mitchell", "Morrison"},
185       {"Marion", "Mitchell", "Morrison"},
186       true},
187
188      // Case-insensative comparisons.
189      {{"Marion", "Mitchell", "Morrison"},
190       {"Marion", "Mitchell", "MORRISON"},
191       true},
192      {{"Marion", "Mitchell", "Morrison"},
193       {"MARION", "Mitchell", "MORRISON"},
194       true},
195      {{"Marion", "Mitchell", "Morrison"},
196       {"MARION", "MITCHELL", "MORRISON"},
197       true},
198      {{"Marion", "", "Mitchell Morrison"},
199       {"MARION", "", "MITCHELL MORRISON"},
200       true},
201      {{"Marion Mitchell", "", "Morrison"},
202       {"MARION MITCHELL", "", "MORRISON"},
203       true},
204
205      // Identical full names but different canonical forms.
206      {{"Marion", "Mitchell", "Morrison"},
207       {"Marion", "", "Mitchell Morrison"},
208       false},
209      {{"Marion", "Mitchell", "Morrison"},
210       {"Marion Mitchell", "", "MORRISON"},
211       false},
212
213      // Different names.
214      {{"Marion", "Mitchell", "Morrison"}, {"Marion", "M.", "Morrison"}, false},
215      {{"Marion", "Mitchell", "Morrison"}, {"MARION", "M.", "MORRISON"}, false},
216      {{"Marion", "Mitchell", "Morrison"},
217       {"David", "Mitchell", "Morrison"},
218       false},
219  };
220
221  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
222    SCOPED_TRACE(base::StringPrintf("i: %" PRIuS, i));
223
224    // Construct the starting_profile.
225    NameInfo starting_profile;
226    starting_profile.SetRawInfo(NAME_FIRST,
227                                ASCIIToUTF16(test_cases[i].starting_names[0]));
228    starting_profile.SetRawInfo(NAME_MIDDLE,
229                                ASCIIToUTF16(test_cases[i].starting_names[1]));
230    starting_profile.SetRawInfo(NAME_LAST,
231                                ASCIIToUTF16(test_cases[i].starting_names[2]));
232
233    // Construct the additional_profile.
234    NameInfo additional_profile;
235    additional_profile.SetRawInfo(
236        NAME_FIRST, ASCIIToUTF16(test_cases[i].additional_names[0]));
237    additional_profile.SetRawInfo(
238        NAME_MIDDLE, ASCIIToUTF16(test_cases[i].additional_names[1]));
239    additional_profile.SetRawInfo(
240        NAME_LAST, ASCIIToUTF16(test_cases[i].additional_names[2]));
241
242    // Verify the test expectations.
243    EXPECT_EQ(test_cases[i].expected_result,
244              starting_profile.ParsedNamesAreEqual(additional_profile));
245  }
246}
247
248}  // namespace autofill
249