1 // Copyright 2019 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/ui/mobile_label_formatter.h"
6 
7 #include <memory>
8 #include <string>
9 #include <vector>
10 
11 #include "base/guid.h"
12 #include "base/strings/string16.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "base/test/scoped_feature_list.h"
15 #include "components/autofill/core/browser/autofill_test_utils.h"
16 #include "components/autofill/core/browser/data_model/autofill_profile.h"
17 #include "components/autofill/core/browser/field_types.h"
18 #include "components/autofill/core/browser/ui/label_formatter_utils.h"
19 #include "components/autofill/core/common/autofill_features.h"
20 #include "testing/gmock/include/gmock/gmock.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22 
23 using testing::ElementsAre;
24 
25 namespace autofill {
26 namespace {
27 
GetContactOnlyFieldTypes()28 std::vector<ServerFieldType> GetContactOnlyFieldTypes() {
29   return {NO_SERVER_DATA, NAME_FIRST, NAME_LAST, EMAIL_ADDRESS,
30           PHONE_HOME_WHOLE_NUMBER};
31 }
32 
GetAddressOnlyFieldTypes()33 std::vector<ServerFieldType> GetAddressOnlyFieldTypes() {
34   return {NO_SERVER_DATA,     NAME_FIRST,
35           NAME_LAST,          ADDRESS_HOME_LINE1,
36           ADDRESS_HOME_LINE2, ADDRESS_HOME_DEPENDENT_LOCALITY,
37           ADDRESS_HOME_CITY,  ADDRESS_HOME_STATE,
38           ADDRESS_HOME_ZIP,   ADDRESS_HOME_COUNTRY};
39 }
40 
GetAddressPlusEmailFieldTypes()41 std::vector<ServerFieldType> GetAddressPlusEmailFieldTypes() {
42   return {NO_SERVER_DATA,
43           NAME_FIRST,
44           NAME_LAST,
45           EMAIL_ADDRESS,
46           ADDRESS_HOME_LINE1,
47           ADDRESS_HOME_LINE2,
48           ADDRESS_HOME_DEPENDENT_LOCALITY,
49           ADDRESS_HOME_CITY,
50           ADDRESS_HOME_STATE,
51           ADDRESS_HOME_ZIP,
52           ADDRESS_HOME_COUNTRY};
53 }
54 
GetAddressPlusContactFieldTypes()55 std::vector<ServerFieldType> GetAddressPlusContactFieldTypes() {
56   return {NO_SERVER_DATA,
57           NAME_FIRST,
58           NAME_LAST,
59           EMAIL_ADDRESS,
60           ADDRESS_HOME_LINE1,
61           ADDRESS_HOME_LINE2,
62           ADDRESS_HOME_DEPENDENT_LOCALITY,
63           ADDRESS_HOME_CITY,
64           ADDRESS_HOME_STATE,
65           ADDRESS_HOME_ZIP,
66           ADDRESS_HOME_COUNTRY,
67           PHONE_HOME_WHOLE_NUMBER};
68 }
69 
GetProfileA()70 AutofillProfile GetProfileA() {
71   AutofillProfile profile =
72       AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
73   test::SetProfileInfo(&profile, "firstA", "middleA", "lastA",
74                        "emailA@gmail.com", "", "address1A", "address2A",
75                        "cityA", "MA", "02113", "US", "16176660000");
76   return profile;
77 }
78 
GetProfileB()79 AutofillProfile GetProfileB() {
80   AutofillProfile profile =
81       AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
82   test::SetProfileInfo(&profile, "firstB", "middleB", "lastB",
83                        "emailB@gmail.com", "", "address1B", "address2B",
84                        "cityB", "NY", "12224", "US", "15185550000");
85   return profile;
86 }
87 
TEST(MobileLabelFormatterTest,GetLabelsWithMissingProfiles)88 TEST(MobileLabelFormatterTest, GetLabelsWithMissingProfiles) {
89   const std::vector<AutofillProfile*> profiles{};
90   const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
91       profiles, "en-US", NAME_FIRST, {NAME_FIRST, NAME_LAST, EMAIL_ADDRESS});
92   EXPECT_TRUE(formatter->GetLabels().empty());
93 }
94 
TEST(MobileLabelFormatterTest,GetLabelsForUnfocusedAddress_ShowOne)95 TEST(MobileLabelFormatterTest, GetLabelsForUnfocusedAddress_ShowOne) {
96   std::map<std::string, std::string> parameters;
97   parameters[features::kAutofillUseMobileLabelDisambiguationParameterName] =
98       features::kAutofillUseMobileLabelDisambiguationParameterShowOne;
99 
100   base::test::ScopedFeatureList features;
101   features.InitAndEnableFeatureWithParameters(
102       features::kAutofillUseMobileLabelDisambiguation, parameters);
103 
104   AutofillProfile profileA = GetProfileA();
105   AutofillProfile profileB = GetProfileB();
106   AutofillProfile profileC =
107       AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
108   test::SetProfileInfo(&profileC, "firstC", "middleC", "lastC", "", "", "", "",
109                        "", "", "", "US", "");
110   const std::vector<AutofillProfile*> profiles{&profileA, &profileB, &profileC};
111 
112   // Tests that the street address is shown when the form contains a street
113   // address field and the user is not focused on it.
114   std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
115       profiles, "en-US", NAME_FIRST, GetAddressOnlyFieldTypes());
116   EXPECT_THAT(formatter->GetLabels(),
117               ElementsAre(base::ASCIIToUTF16("address1A, address2A"),
118                           base::ASCIIToUTF16("address1B, address2B"),
119                           base::string16()));
120 
121   // Tests that the non street address is shown when the form's only address
122   // fields are non street address fields and the user is not focused on any of
123   // them.
124   formatter = LabelFormatter::Create(profiles, "en-US", NAME_FIRST,
125                                      {NAME_FIRST, NAME_LAST, ADDRESS_HOME_ZIP});
126   EXPECT_THAT(formatter->GetLabels(),
127               ElementsAre(base::ASCIIToUTF16("02113"),
128                           base::ASCIIToUTF16("12224"), base::string16()));
129 
130   // Like the previous test, but without name.
131   formatter = LabelFormatter::Create(
132       profiles, "en-US", EMAIL_ADDRESS,
133       {ADDRESS_HOME_CITY, ADDRESS_HOME_STATE, EMAIL_ADDRESS});
134   EXPECT_THAT(formatter->GetLabels(),
135               ElementsAre(base::ASCIIToUTF16("cityA, MA"),
136                           base::ASCIIToUTF16("cityB, NY"), base::string16()));
137 
138   // Tests that addresses are not shown when the form does not contain an
139   // address field.
140   formatter = LabelFormatter::Create(profiles, "en-US", NAME_FIRST,
141                                      GetContactOnlyFieldTypes());
142   EXPECT_THAT(
143       formatter->GetLabels(),
144       ElementsAre(base::ASCIIToUTF16("(617) 666-0000"),
145                   base::ASCIIToUTF16("(518) 555-0000"), base::string16()));
146 }
147 
TEST(MobileLabelFormatterTest,GetLabelsForFocusedAddress_MultipleProfiles_ShowOne)148 TEST(MobileLabelFormatterTest,
149      GetLabelsForFocusedAddress_MultipleProfiles_ShowOne) {
150   std::map<std::string, std::string> parameters;
151   parameters[features::kAutofillUseMobileLabelDisambiguationParameterName] =
152       features::kAutofillUseMobileLabelDisambiguationParameterShowOne;
153 
154   base::test::ScopedFeatureList features;
155   features.InitAndEnableFeatureWithParameters(
156       features::kAutofillUseMobileLabelDisambiguation, parameters);
157 
158   AutofillProfile profileA = GetProfileA();
159 
160   // Tests that a street is shown when a form contains an unfocused street
161   // address and a focused non street address.
162   AutofillProfile profileB = GetProfileB();
163   std::vector<AutofillProfile*> profiles{&profileA, &profileB};
164 
165   std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
166       profiles, "en-US", ADDRESS_HOME_ZIP, GetAddressPlusContactFieldTypes());
167   EXPECT_THAT(formatter->GetLabels(),
168               ElementsAre(base::ASCIIToUTF16("address1A, address2A"),
169                           base::ASCIIToUTF16("address1B, address2B")));
170 
171   // Tests that a non street address is shown when a form contains only
172   // non focused street address fields and a focused non street address.
173   formatter = LabelFormatter::Create(
174       profiles, "en-US", ADDRESS_HOME_ZIP,
175       {ADDRESS_HOME_CITY, ADDRESS_HOME_STATE, ADDRESS_HOME_ZIP});
176   EXPECT_THAT(formatter->GetLabels(),
177               ElementsAre(base::ASCIIToUTF16("cityA, MA"),
178                           base::ASCIIToUTF16("cityB, NY")));
179 
180   // Tests that a non street address is not shown when a form contains
181   // non focused street address fields and another kind of field and also has a
182   // focused non street address.
183   formatter = LabelFormatter::Create(
184       profiles, "en-US", ADDRESS_HOME_CITY,
185       {ADDRESS_HOME_CITY, ADDRESS_HOME_STATE, EMAIL_ADDRESS});
186   EXPECT_THAT(formatter->GetLabels(),
187               ElementsAre(base::ASCIIToUTF16("emailA@gmail.com"),
188                           base::ASCIIToUTF16("emailB@gmail.com")));
189 
190   // Tests that a phone number is shown when the address cannot be shown and
191   // there are different phone numbers.
192   profileB = GetProfileA();
193   profileB.SetInfo(PHONE_HOME_WHOLE_NUMBER, base::ASCIIToUTF16("15185550000"),
194                    "en-US");
195   profiles = {&profileA, &profileB};
196 
197   formatter = LabelFormatter::Create(profiles, "en-US", ADDRESS_HOME_LINE1,
198                                      GetAddressPlusContactFieldTypes());
199   EXPECT_THAT(formatter->GetLabels(),
200               ElementsAre(base::ASCIIToUTF16("(617) 666-0000"),
201                           base::ASCIIToUTF16("(518) 555-0000")));
202 
203   // Tests that an email address is shown when the address cannot be shown and
204   // there are different email addresses.
205   profileB = GetProfileA();
206   profileB.SetInfo(EMAIL_ADDRESS, base::ASCIIToUTF16("emailB@gmail.com"),
207                    "en-US");
208   profiles = {&profileA, &profileB};
209 
210   formatter = LabelFormatter::Create(profiles, "en-US", ADDRESS_HOME_LINE1,
211                                      GetAddressPlusContactFieldTypes());
212   EXPECT_THAT(formatter->GetLabels(),
213               ElementsAre(base::ASCIIToUTF16("emailA@gmail.com"),
214                           base::ASCIIToUTF16("emailB@gmail.com")));
215 
216   // Tests that a name is shown when the address cannot be shown and there are
217   // different names.
218   profileB = GetProfileA();
219   profileB.SetInfo(NAME_FIRST, base::ASCIIToUTF16("firstB"), "en-US");
220   profileB.SetInfo(NAME_LAST, base::ASCIIToUTF16("lastB"), "en-US");
221   profiles = {&profileA, &profileB};
222 
223   formatter = LabelFormatter::Create(profiles, "en-US", ADDRESS_HOME_LINE1,
224                                      GetAddressPlusContactFieldTypes());
225   EXPECT_THAT(formatter->GetLabels(),
226               ElementsAre(base::ASCIIToUTF16("firstA lastA"),
227                           base::ASCIIToUTF16("firstB lastB")));
228 
229   // Tests that a phone number is shown when the address cannot be shown, when
230   // profiles have the same data for unfocused form fields, and when the form
231   // has a phone number field.
232   profileB = GetProfileA();
233   profiles = {&profileA, &profileB};
234   formatter = LabelFormatter::Create(profiles, "en-US", ADDRESS_HOME_LINE1,
235                                      GetAddressPlusContactFieldTypes());
236   EXPECT_THAT(formatter->GetLabels(),
237               ElementsAre(base::ASCIIToUTF16("(617) 666-0000"),
238                           base::ASCIIToUTF16("(617) 666-0000")));
239 
240   // Tests that an email address is shown when the address cannot be shown, when
241   // profiles have the same data for unfocused form fields, and when the form
242   // does not have a phone number field, but has an email address field.
243   profileB = GetProfileA();
244   profiles = {&profileA, &profileB};
245   formatter = LabelFormatter::Create(profiles, "en-US", ADDRESS_HOME_LINE1,
246                                      GetAddressPlusEmailFieldTypes());
247   EXPECT_THAT(formatter->GetLabels(),
248               ElementsAre(base::ASCIIToUTF16("emailA@gmail.com"),
249                           base::ASCIIToUTF16("emailA@gmail.com")));
250 
251   // Tests that a name is shown when the address cannot be shown, when profiles
252   // have the same data for unfocused form fields, and when the form does not
253   // have a phone number or email address field, but has a name field.
254   profileB = GetProfileA();
255   profiles = {&profileA, &profileB};
256   formatter = LabelFormatter::Create(profiles, "en-US", ADDRESS_HOME_LINE1,
257                                      GetAddressOnlyFieldTypes());
258   EXPECT_THAT(formatter->GetLabels(),
259               ElementsAre(base::ASCIIToUTF16("firstA lastA"),
260                           base::ASCIIToUTF16("firstA lastA")));
261 }
262 
TEST(MobileLabelFormatterTest,GetLabelsForFocusedAddress_UniqueProfile_ShowOne)263 TEST(MobileLabelFormatterTest,
264      GetLabelsForFocusedAddress_UniqueProfile_ShowOne) {
265   std::map<std::string, std::string> parameters;
266   parameters[features::kAutofillUseMobileLabelDisambiguationParameterName] =
267       features::kAutofillUseMobileLabelDisambiguationParameterShowOne;
268 
269   base::test::ScopedFeatureList features;
270   features.InitAndEnableFeatureWithParameters(
271       features::kAutofillUseMobileLabelDisambiguation, parameters);
272 
273   AutofillProfile profileA = GetProfileA();
274   std::vector<AutofillProfile*> profiles{&profileA};
275 
276   // Tests that the second most important piece of data, phone, is shown when
277   // the form has an unfocused form field corresponding to this data and the
278   // most important piece cannot be shown.
279   std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
280       profiles, "en-US", ADDRESS_HOME_LINE1, GetAddressPlusContactFieldTypes());
281   EXPECT_THAT(formatter->GetLabels(),
282               ElementsAre(base::ASCIIToUTF16("(617) 666-0000")));
283 
284   // Tests that the third most important piece of data, email, is shown when
285   // the form has an unfocused form field corresponding to this data and the
286   // two most important pieces of data cannot be shown.
287   formatter = LabelFormatter::Create(profiles, "en-US", ADDRESS_HOME_LINE1,
288                                      GetAddressPlusEmailFieldTypes());
289   EXPECT_THAT(formatter->GetLabels(),
290               ElementsAre(base::ASCIIToUTF16("emailA@gmail.com")));
291 
292   // Tests that the least important piece of data, name, is shown when the form
293   // has an unfocused form field corresponding to this data and the more
294   // important pieces of data cannot be shown.
295   formatter = LabelFormatter::Create(profiles, "en-US", ADDRESS_HOME_LINE1,
296                                      GetAddressOnlyFieldTypes());
297   EXPECT_THAT(formatter->GetLabels(),
298               ElementsAre(base::ASCIIToUTF16("firstA lastA")));
299 }
300 
TEST(MobileLabelFormatterTest,GetLabels_DistinctProfiles_ShowAll)301 TEST(MobileLabelFormatterTest, GetLabels_DistinctProfiles_ShowAll) {
302   std::map<std::string, std::string> parameters;
303   parameters[features::kAutofillUseMobileLabelDisambiguationParameterName] =
304       features::kAutofillUseMobileLabelDisambiguationParameterShowAll;
305 
306   base::test::ScopedFeatureList features;
307   features.InitAndEnableFeatureWithParameters(
308       features::kAutofillUseMobileLabelDisambiguation, parameters);
309 
310   AutofillProfile profileA = GetProfileA();
311   AutofillProfile profileB = GetProfileB();
312   AutofillProfile profileC =
313       AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
314   test::SetProfileInfo(&profileC, "firstC", "middleC", "lastC", "", "", "", "",
315                        "", "", "", "US", "");
316   const std::vector<AutofillProfile*> profiles{&profileA, &profileB, &profileC};
317 
318   // Tests that unfocused data that is not the same across profiles is shown in
319   // the label for forms with addresses.
320   std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
321       profiles, "en-US", NAME_FIRST, GetAddressPlusContactFieldTypes());
322   EXPECT_THAT(
323       formatter->GetLabels(),
324       ElementsAre(base::ASCIIToUTF16(
325                       "address1A, address2A, (617) 666-0000, emailA@gmail.com"),
326                   base::ASCIIToUTF16(
327                       "address1B, address2B, (518) 555-0000, emailB@gmail.com"),
328                   base::string16()));
329 
330   // Like the previous test, but focuses on an address field rather than a name
331   // field to check that the name is correctly added to the label.
332   formatter = LabelFormatter::Create(profiles, "en-US", ADDRESS_HOME_LINE1,
333                                      GetAddressPlusContactFieldTypes());
334   EXPECT_THAT(
335       formatter->GetLabels(),
336       ElementsAre(
337           base::ASCIIToUTF16("firstA, (617) 666-0000, emailA@gmail.com"),
338           base::ASCIIToUTF16("firstB, (518) 555-0000, emailB@gmail.com"),
339           base::ASCIIToUTF16("firstC")));
340 
341   // Tests that unfocused data that is not the same across profiles is shown in
342   // the label for forms with non street addresses and without street addresses.
343   formatter = LabelFormatter::Create(profiles, "en-US", NAME_FIRST,
344                                      {NAME_FIRST, NAME_LAST, ADDRESS_HOME_ZIP});
345   EXPECT_THAT(formatter->GetLabels(),
346               ElementsAre(base::ASCIIToUTF16("02113"),
347                           base::ASCIIToUTF16("12224"), base::string16()));
348 
349   // Like the previous test, but focuses on an address field rather than a name
350   // field to check that the name is correctly added to the label.
351   formatter = LabelFormatter::Create(profiles, "en-US", ADDRESS_HOME_ZIP,
352                                      {NAME_FIRST, NAME_LAST, ADDRESS_HOME_ZIP});
353   EXPECT_THAT(
354       formatter->GetLabels(),
355       ElementsAre(base::ASCIIToUTF16("firstA"), base::ASCIIToUTF16("firstB"),
356                   base::ASCIIToUTF16("firstC")));
357 
358   // Tests that unfocused data that is not the same across profiles is shown in
359   // the label for forms without addresses.
360   formatter = LabelFormatter::Create(profiles, "en-US", NAME_FIRST,
361                                      GetContactOnlyFieldTypes());
362   EXPECT_THAT(
363       formatter->GetLabels(),
364       ElementsAre(base::ASCIIToUTF16("(617) 666-0000, emailA@gmail.com"),
365                   base::ASCIIToUTF16("(518) 555-0000, emailB@gmail.com"),
366                   base::string16()));
367 
368   // Like the previous test, but focuses on a phone field rather than a name
369   // field to check that the name is correctly added to the label.
370   formatter = LabelFormatter::Create(profiles, "en-US", PHONE_HOME_WHOLE_NUMBER,
371                                      GetContactOnlyFieldTypes());
372   EXPECT_THAT(formatter->GetLabels(),
373               ElementsAre(base::ASCIIToUTF16("firstA, emailA@gmail.com"),
374                           base::ASCIIToUTF16("firstB, emailB@gmail.com"),
375                           base::ASCIIToUTF16("firstC")));
376 }
377 
TEST(MobileLabelFormatterTest,GetDefaultLabel_ShowAll)378 TEST(MobileLabelFormatterTest, GetDefaultLabel_ShowAll) {
379   std::map<std::string, std::string> parameters;
380   parameters[features::kAutofillUseMobileLabelDisambiguationParameterName] =
381       features::kAutofillUseMobileLabelDisambiguationParameterShowAll;
382 
383   base::test::ScopedFeatureList features;
384   features.InitAndEnableFeatureWithParameters(
385       features::kAutofillUseMobileLabelDisambiguation, parameters);
386 
387   AutofillProfile profileA = GetProfileA();
388   const std::vector<AutofillProfile*> profiles{&profileA};
389 
390   // Tests that the most important piece of data, address, is shown when the
391   // form has an unfocused form field corresponding to this data.
392   std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
393       profiles, "en-US", NAME_FIRST, GetAddressPlusContactFieldTypes());
394   EXPECT_THAT(formatter->GetLabels(),
395               ElementsAre(base::ASCIIToUTF16("address1A, address2A")));
396 
397   // Tests that the most important piece of data, address, is shown when the
398   // form has an unfocused form field corresponding to this data.
399   formatter = LabelFormatter::Create(profiles, "en-US", NAME_FIRST,
400                                      {NAME_FIRST, NAME_LAST, ADDRESS_HOME_ZIP});
401   EXPECT_THAT(formatter->GetLabels(), ElementsAre(base::ASCIIToUTF16("02113")));
402 
403   // Tests that the second most important piece of data, phone, is shown when
404   // the form has an unfocused form field corresponding to this data and the
405   // most important piece cannot be shown.
406   formatter = LabelFormatter::Create(profiles, "en-US", ADDRESS_HOME_LINE1,
407                                      GetAddressPlusContactFieldTypes());
408   EXPECT_THAT(formatter->GetLabels(),
409               ElementsAre(base::ASCIIToUTF16("(617) 666-0000")));
410 
411   // Tests that the third most important piece of data, email, is shown when
412   // the form has an unfocused form field corresponding to this data and the
413   // two more important pieces of data cannot be shown.
414   formatter = LabelFormatter::Create(profiles, "en-US", PHONE_HOME_WHOLE_NUMBER,
415                                      GetContactOnlyFieldTypes());
416   EXPECT_THAT(formatter->GetLabels(),
417               ElementsAre(base::ASCIIToUTF16("emailA@gmail.com")));
418 
419   // Tests that the least important piece of data, name, is shown when
420   // the form has an unfocused form field corresponding to this data and the
421   // more important pieces of data cannot be shown.
422   formatter =
423       LabelFormatter::Create(profiles, "en-US", PHONE_HOME_WHOLE_NUMBER,
424                              {NAME_FIRST, NAME_LAST, PHONE_HOME_WHOLE_NUMBER});
425   EXPECT_THAT(formatter->GetLabels(),
426               ElementsAre(base::ASCIIToUTF16("firstA lastA")));
427 
428   // Tests that a non street address is shown when a form contains only
429   // non focused street address fields and a focused non street address.
430   formatter = LabelFormatter::Create(
431       profiles, "en-US", ADDRESS_HOME_ZIP,
432       {ADDRESS_HOME_CITY, ADDRESS_HOME_STATE, ADDRESS_HOME_ZIP});
433   EXPECT_THAT(formatter->GetLabels(),
434               ElementsAre(base::ASCIIToUTF16("cityA, MA")));
435 
436   // Tests that a non street address is not shown when a form contains
437   // non focused street address fields and another kind of field and also has a
438   // focused non street address.
439   formatter = LabelFormatter::Create(
440       profiles, "en-US", ADDRESS_HOME_CITY,
441       {ADDRESS_HOME_CITY, ADDRESS_HOME_STATE, EMAIL_ADDRESS});
442   EXPECT_THAT(formatter->GetLabels(),
443               ElementsAre(base::ASCIIToUTF16("emailA@gmail.com")));
444 }
445 
446 }  // namespace
447 }  // namespace autofill