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