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/form_parsing/address_field.h"
6 
7 #include <memory>
8 #include <vector>
9 
10 #include "base/macros.h"
11 #include "base/memory/ptr_util.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_field.h"
16 #include "components/autofill/core/browser/form_parsing/autofill_scanner.h"
17 #include "components/autofill/core/browser/pattern_provider/test_pattern_provider.h"
18 #include "components/autofill/core/common/autofill_features.h"
19 #include "components/autofill/core/common/form_field_data.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 
22 using base::ASCIIToUTF16;
23 
24 namespace autofill {
25 
26 class AddressFieldTest : public testing::Test {
27  public:
28   AddressFieldTest() = default;
29   AddressFieldTest(const AddressFieldTest&) = delete;
30   AddressFieldTest& operator=(const AddressFieldTest&) = delete;
31 
32  protected:
33   // Downcast for tests.
Parse(AutofillScanner * scanner)34   static std::unique_ptr<AddressField> Parse(AutofillScanner* scanner) {
35     // An empty page_language means the language is unknown and patterns of all
36     // languages are used.
37     std::unique_ptr<FormField> field =
38         AddressField::Parse(scanner, /*page_language=*/"", nullptr);
39     return std::unique_ptr<AddressField>(
40         static_cast<AddressField*>(field.release()));
41   }
42 
43   std::vector<std::unique_ptr<AutofillField>> list_;
44   std::unique_ptr<AddressField> field_;
45   FieldCandidatesMap field_candidates_map_;
46 
47   // RAII object to mock the the PatternProvider.
48   TestPatternProvider test_pattern_provider_;
49 };
50 
TEST_F(AddressFieldTest,Empty)51 TEST_F(AddressFieldTest, Empty) {
52   AutofillScanner scanner(list_);
53   field_ = Parse(&scanner);
54   ASSERT_EQ(nullptr, field_.get());
55 }
56 
TEST_F(AddressFieldTest,NonParse)57 TEST_F(AddressFieldTest, NonParse) {
58   list_.push_back(std::make_unique<AutofillField>());
59   AutofillScanner scanner(list_);
60   field_ = Parse(&scanner);
61   ASSERT_EQ(nullptr, field_.get());
62 }
63 
TEST_F(AddressFieldTest,ParseOneLineAddress)64 TEST_F(AddressFieldTest, ParseOneLineAddress) {
65   FormFieldData field;
66   field.form_control_type = "text";
67 
68   field.label = ASCIIToUTF16("Address");
69   field.name = ASCIIToUTF16("address");
70   list_.push_back(
71       std::make_unique<AutofillField>(field, ASCIIToUTF16("addr1")));
72 
73   AutofillScanner scanner(list_);
74   field_ = Parse(&scanner);
75   ASSERT_NE(nullptr, field_.get());
76   field_->AddClassificationsForTesting(&field_candidates_map_);
77   ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("addr1")) !=
78               field_candidates_map_.end());
79   EXPECT_EQ(ADDRESS_HOME_LINE1,
80             field_candidates_map_[ASCIIToUTF16("addr1")].BestHeuristicType());
81 }
82 
TEST_F(AddressFieldTest,ParseTwoLineAddress)83 TEST_F(AddressFieldTest, ParseTwoLineAddress) {
84   FormFieldData field;
85   field.form_control_type = "text";
86 
87   field.label = ASCIIToUTF16("Address");
88   field.name = ASCIIToUTF16("address");
89   list_.push_back(
90       std::make_unique<AutofillField>(field, ASCIIToUTF16("addr1")));
91 
92   field.label = base::string16();
93   field.name = ASCIIToUTF16("address2");
94   list_.push_back(
95       std::make_unique<AutofillField>(field, ASCIIToUTF16("addr2")));
96 
97   AutofillScanner scanner(list_);
98   field_ = Parse(&scanner);
99   ASSERT_NE(nullptr, field_.get());
100   field_->AddClassificationsForTesting(&field_candidates_map_);
101   ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("addr1")) !=
102               field_candidates_map_.end());
103   EXPECT_EQ(ADDRESS_HOME_LINE1,
104             field_candidates_map_[ASCIIToUTF16("addr1")].BestHeuristicType());
105   ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("addr2")) !=
106               field_candidates_map_.end());
107   EXPECT_EQ(ADDRESS_HOME_LINE2,
108             field_candidates_map_[ASCIIToUTF16("addr2")].BestHeuristicType());
109 }
110 
TEST_F(AddressFieldTest,ParseThreeLineAddress)111 TEST_F(AddressFieldTest, ParseThreeLineAddress) {
112   FormFieldData field;
113   field.form_control_type = "text";
114 
115   field.label = ASCIIToUTF16("Address Line1");
116   field.name = ASCIIToUTF16("Address1");
117   list_.push_back(
118       std::make_unique<AutofillField>(field, ASCIIToUTF16("addr1")));
119 
120   field.label = ASCIIToUTF16("Address Line2");
121   field.name = ASCIIToUTF16("Address2");
122   list_.push_back(
123       std::make_unique<AutofillField>(field, ASCIIToUTF16("addr2")));
124 
125   field.label = ASCIIToUTF16("Address Line3");
126   field.name = ASCIIToUTF16("Address3");
127   list_.push_back(
128       std::make_unique<AutofillField>(field, ASCIIToUTF16("addr3")));
129 
130   AutofillScanner scanner(list_);
131   field_ = Parse(&scanner);
132   ASSERT_NE(nullptr, field_.get());
133   field_->AddClassificationsForTesting(&field_candidates_map_);
134   ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("addr1")) !=
135               field_candidates_map_.end());
136   EXPECT_EQ(ADDRESS_HOME_LINE1,
137             field_candidates_map_[ASCIIToUTF16("addr1")].BestHeuristicType());
138   ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("addr2")) !=
139               field_candidates_map_.end());
140   EXPECT_EQ(ADDRESS_HOME_LINE2,
141             field_candidates_map_[ASCIIToUTF16("addr2")].BestHeuristicType());
142   ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("addr3")) !=
143               field_candidates_map_.end());
144   EXPECT_EQ(ADDRESS_HOME_LINE3,
145             field_candidates_map_[ASCIIToUTF16("addr3")].BestHeuristicType());
146 }
147 
TEST_F(AddressFieldTest,ParseStreetAddressFromTextArea)148 TEST_F(AddressFieldTest, ParseStreetAddressFromTextArea) {
149   FormFieldData field;
150   field.form_control_type = "textarea";
151 
152   field.label = ASCIIToUTF16("Address");
153   field.name = ASCIIToUTF16("address");
154   list_.push_back(std::make_unique<AutofillField>(field, ASCIIToUTF16("addr")));
155 
156   AutofillScanner scanner(list_);
157   field_ = Parse(&scanner);
158   ASSERT_NE(nullptr, field_.get());
159   field_->AddClassificationsForTesting(&field_candidates_map_);
160   ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("addr")) !=
161               field_candidates_map_.end());
162   EXPECT_EQ(ADDRESS_HOME_STREET_ADDRESS,
163             field_candidates_map_[ASCIIToUTF16("addr")].BestHeuristicType());
164 }
165 
166 // Tests that fields are classified as |ADDRESS_HOME_STREET_NAME| and
167 // |ADDRESS_HOME_HOUSE_NUMBER| when they are labeled accordingly and
168 // both are present.
TEST_F(AddressFieldTest,ParseStreetNameAndHouseNumber)169 TEST_F(AddressFieldTest, ParseStreetNameAndHouseNumber) {
170   // TODO(crbug.com/1125978): Remove once launched.
171   base::test::ScopedFeatureList enabled;
172   enabled.InitAndEnableFeature(
173       features::kAutofillEnableSupportForMoreStructureInAddresses);
174 
175   FormFieldData field;
176   field.form_control_type = "text";
177 
178   field.label = ASCIIToUTF16("Street");
179   field.name = ASCIIToUTF16("street");
180   list_.push_back(
181       std::make_unique<AutofillField>(field, ASCIIToUTF16("street")));
182 
183   field.label = ASCIIToUTF16("House number");
184   field.name = ASCIIToUTF16("house-number");
185   list_.push_back(
186       std::make_unique<AutofillField>(field, ASCIIToUTF16("house")));
187 
188   AutofillScanner scanner(list_);
189   field_ = Parse(&scanner);
190   ASSERT_NE(nullptr, field_.get());
191   field_->AddClassificationsForTesting(&field_candidates_map_);
192 
193   ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("street")) !=
194               field_candidates_map_.end());
195   EXPECT_EQ(ADDRESS_HOME_STREET_NAME,
196             field_candidates_map_[ASCIIToUTF16("street")].BestHeuristicType());
197 
198   ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("house")) !=
199               field_candidates_map_.end());
200   EXPECT_EQ(ADDRESS_HOME_HOUSE_NUMBER,
201             field_candidates_map_[ASCIIToUTF16("house")].BestHeuristicType());
202 }
203 
204 // Tests that the field is not classified as |ADDRESS_HOME_STREET_NAME| when
205 // it is labeled accordingly but adjacent field classified as
206 // |ADDRESS_HOME_HOUSE_NUMBER| is absent.
TEST_F(AddressFieldTest,NotParseStreetNameWithoutHouseNumber)207 TEST_F(AddressFieldTest, NotParseStreetNameWithoutHouseNumber) {
208   // TODO(crbug.com/1125978): Remove once launched.
209   base::test::ScopedFeatureList enabled;
210   enabled.InitAndEnableFeature(
211       features::kAutofillEnableSupportForMoreStructureInAddresses);
212 
213   FormFieldData field;
214   field.form_control_type = "text";
215 
216   field.label = ASCIIToUTF16("Street");
217   field.name = ASCIIToUTF16("street");
218   list_.push_back(
219       std::make_unique<AutofillField>(field, ASCIIToUTF16("street")));
220 
221   AutofillScanner scanner(list_);
222   field_ = Parse(&scanner);
223 
224   if (!field_.get())
225     return;
226   field_->AddClassificationsForTesting(&field_candidates_map_);
227   if (field_candidates_map_.empty())
228     return;
229 
230   EXPECT_NE(ADDRESS_HOME_STREET_NAME,
231             field_candidates_map_[ASCIIToUTF16("street")].BestHeuristicType());
232 }
233 
234 // Tests that the field is not classified as |ADDRESS_HOME_HOUSE_NUMBER| when
235 // it is labeled accordingly but adjacent field classified as
236 // |ADDRESS_HOME_STREET_NAME| is absent.
TEST_F(AddressFieldTest,NotParseHouseNumberWithoutStreetName)237 TEST_F(AddressFieldTest, NotParseHouseNumberWithoutStreetName) {
238   // TODO(crbug.com/1125978): Remove once launched.
239   base::test::ScopedFeatureList enabled;
240   enabled.InitAndEnableFeature(
241       features::kAutofillEnableSupportForMoreStructureInAddresses);
242 
243   FormFieldData field;
244   field.form_control_type = "text";
245 
246   field.label = ASCIIToUTF16("House number");
247   field.name = ASCIIToUTF16("house-number");
248   list_.push_back(
249       std::make_unique<AutofillField>(field, ASCIIToUTF16("house")));
250 
251   AutofillScanner scanner(list_);
252   field_ = Parse(&scanner);
253 
254   if (!field_.get())
255     return;
256   field_->AddClassificationsForTesting(&field_candidates_map_);
257   if (field_candidates_map_.empty())
258     return;
259 
260   EXPECT_NE(ADDRESS_HOME_HOUSE_NUMBER,
261             field_candidates_map_[ASCIIToUTF16("house")].BestHeuristicType());
262 }
263 
TEST_F(AddressFieldTest,ParseCity)264 TEST_F(AddressFieldTest, ParseCity) {
265   FormFieldData field;
266   field.form_control_type = "text";
267 
268   field.label = ASCIIToUTF16("City");
269   field.name = ASCIIToUTF16("city");
270   list_.push_back(
271       std::make_unique<AutofillField>(field, ASCIIToUTF16("city1")));
272 
273   AutofillScanner scanner(list_);
274   field_ = Parse(&scanner);
275   ASSERT_NE(nullptr, field_.get());
276   field_->AddClassificationsForTesting(&field_candidates_map_);
277   ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("city1")) !=
278               field_candidates_map_.end());
279   EXPECT_EQ(ADDRESS_HOME_CITY,
280             field_candidates_map_[ASCIIToUTF16("city1")].BestHeuristicType());
281 }
282 
TEST_F(AddressFieldTest,ParseState)283 TEST_F(AddressFieldTest, ParseState) {
284   FormFieldData field;
285   field.form_control_type = "text";
286 
287   field.label = ASCIIToUTF16("State");
288   field.name = ASCIIToUTF16("state");
289   list_.push_back(
290       std::make_unique<AutofillField>(field, ASCIIToUTF16("state1")));
291 
292   AutofillScanner scanner(list_);
293   field_ = Parse(&scanner);
294   ASSERT_NE(nullptr, field_.get());
295   field_->AddClassificationsForTesting(&field_candidates_map_);
296   ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("state1")) !=
297               field_candidates_map_.end());
298   EXPECT_EQ(ADDRESS_HOME_STATE,
299             field_candidates_map_[ASCIIToUTF16("state1")].BestHeuristicType());
300 }
301 
TEST_F(AddressFieldTest,ParseZip)302 TEST_F(AddressFieldTest, ParseZip) {
303   FormFieldData field;
304   field.form_control_type = "text";
305 
306   field.label = ASCIIToUTF16("Zip");
307   field.name = ASCIIToUTF16("zip");
308   list_.push_back(std::make_unique<AutofillField>(field, ASCIIToUTF16("zip1")));
309 
310   AutofillScanner scanner(list_);
311   field_ = Parse(&scanner);
312   ASSERT_NE(nullptr, field_.get());
313   field_->AddClassificationsForTesting(&field_candidates_map_);
314   ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("zip1")) !=
315               field_candidates_map_.end());
316   EXPECT_EQ(ADDRESS_HOME_ZIP,
317             field_candidates_map_[ASCIIToUTF16("zip1")].BestHeuristicType());
318 }
319 
TEST_F(AddressFieldTest,ParseStateAndZipOneLabel)320 TEST_F(AddressFieldTest, ParseStateAndZipOneLabel) {
321   FormFieldData field;
322   field.form_control_type = "text";
323 
324   field.label = ASCIIToUTF16("State/Province, Zip/Postal Code");
325   field.name = ASCIIToUTF16("state");
326   list_.push_back(
327       std::make_unique<AutofillField>(field, ASCIIToUTF16("state")));
328 
329   field.label = ASCIIToUTF16("State/Province, Zip/Postal Code");
330   field.name = ASCIIToUTF16("zip");
331   list_.push_back(std::make_unique<AutofillField>(field, ASCIIToUTF16("zip")));
332 
333   AutofillScanner scanner(list_);
334   field_ = Parse(&scanner);
335   ASSERT_NE(nullptr, field_.get());
336   field_->AddClassificationsForTesting(&field_candidates_map_);
337   ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("state")) !=
338               field_candidates_map_.end());
339   EXPECT_EQ(ADDRESS_HOME_STATE,
340             field_candidates_map_[ASCIIToUTF16("state")].BestHeuristicType());
341   ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("zip")) !=
342               field_candidates_map_.end());
343   EXPECT_EQ(ADDRESS_HOME_ZIP,
344             field_candidates_map_[ASCIIToUTF16("zip")].BestHeuristicType());
345 }
346 
TEST_F(AddressFieldTest,ParseCountry)347 TEST_F(AddressFieldTest, ParseCountry) {
348   FormFieldData field;
349   field.form_control_type = "text";
350 
351   field.label = ASCIIToUTF16("Country");
352   field.name = ASCIIToUTF16("country");
353   list_.push_back(
354       std::make_unique<AutofillField>(field, ASCIIToUTF16("country1")));
355 
356   AutofillScanner scanner(list_);
357   field_ = Parse(&scanner);
358   ASSERT_NE(nullptr, field_.get());
359   field_->AddClassificationsForTesting(&field_candidates_map_);
360   ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("country1")) !=
361               field_candidates_map_.end());
362   EXPECT_EQ(
363       ADDRESS_HOME_COUNTRY,
364       field_candidates_map_[ASCIIToUTF16("country1")].BestHeuristicType());
365 }
366 
TEST_F(AddressFieldTest,ParseCompany)367 TEST_F(AddressFieldTest, ParseCompany) {
368   FormFieldData field;
369   field.form_control_type = "text";
370 
371   field.label = ASCIIToUTF16("Company");
372   field.name = ASCIIToUTF16("company");
373   list_.push_back(
374       std::make_unique<AutofillField>(field, ASCIIToUTF16("company1")));
375 
376   AutofillScanner scanner(list_);
377   field_ = Parse(&scanner);
378   ASSERT_NE(nullptr, field_.get());
379   field_->AddClassificationsForTesting(&field_candidates_map_);
380   ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("company1")) !=
381               field_candidates_map_.end());
382   EXPECT_EQ(
383       COMPANY_NAME,
384       field_candidates_map_[ASCIIToUTF16("company1")].BestHeuristicType());
385 }
386 
387 // Tests that the city, state, country and zip-code fields are correctly
388 // classfied with unambiguous field names and labels.
TEST_F(AddressFieldTest,ParseCityStateCountryZipcodeTogether)389 TEST_F(AddressFieldTest, ParseCityStateCountryZipcodeTogether) {
390   FormFieldData field;
391   field.form_control_type = "text";
392 
393   field.label = ASCIIToUTF16("City");
394   field.name = ASCIIToUTF16("city");
395   list_.push_back(
396       std::make_unique<AutofillField>(field, ASCIIToUTF16("city1")));
397 
398   field.label = ASCIIToUTF16("State");
399   field.name = ASCIIToUTF16("state");
400   list_.push_back(
401       std::make_unique<AutofillField>(field, ASCIIToUTF16("state1")));
402 
403   field.label = ASCIIToUTF16("Country");
404   field.name = ASCIIToUTF16("country");
405   list_.push_back(
406       std::make_unique<AutofillField>(field, ASCIIToUTF16("country1")));
407 
408   field.label = ASCIIToUTF16("Zip");
409   field.name = ASCIIToUTF16("zip");
410   list_.push_back(std::make_unique<AutofillField>(field, ASCIIToUTF16("zip1")));
411 
412   AutofillScanner scanner(list_);
413   field_ = Parse(&scanner);
414   ASSERT_NE(nullptr, field_.get());
415   field_->AddClassificationsForTesting(&field_candidates_map_);
416 
417   ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("city1")) !=
418               field_candidates_map_.end());
419   EXPECT_EQ(ADDRESS_HOME_CITY,
420             field_candidates_map_[ASCIIToUTF16("city1")].BestHeuristicType());
421 
422   ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("state1")) !=
423               field_candidates_map_.end());
424   EXPECT_EQ(ADDRESS_HOME_STATE,
425             field_candidates_map_[ASCIIToUTF16("state1")].BestHeuristicType());
426 
427   ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("country1")) !=
428               field_candidates_map_.end());
429   EXPECT_EQ(
430       ADDRESS_HOME_COUNTRY,
431       field_candidates_map_[ASCIIToUTF16("country1")].BestHeuristicType());
432 
433   ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("zip1")) !=
434               field_candidates_map_.end());
435   EXPECT_EQ(ADDRESS_HOME_ZIP,
436             field_candidates_map_[ASCIIToUTF16("zip1")].BestHeuristicType());
437 }
438 
439 // Tests that the field is classified as |ADDRESS_HOME_COUNTRY| when the field
440 // label contains 'Region'.
TEST_F(AddressFieldTest,ParseCountryLabelRegion)441 TEST_F(AddressFieldTest, ParseCountryLabelRegion) {
442   FormFieldData field;
443   field.form_control_type = "text";
444 
445   field.label = ASCIIToUTF16("Country/Region");
446   field.name = ASCIIToUTF16("country");
447   list_.push_back(
448       std::make_unique<AutofillField>(field, ASCIIToUTF16("country1")));
449 
450   AutofillScanner scanner(list_);
451   field_ = Parse(&scanner);
452   ASSERT_NE(nullptr, field_.get());
453   field_->AddClassificationsForTesting(&field_candidates_map_);
454 
455   ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("country1")) !=
456               field_candidates_map_.end());
457   EXPECT_EQ(
458       ADDRESS_HOME_COUNTRY,
459       field_candidates_map_[ASCIIToUTF16("country1")].BestHeuristicType());
460 }
461 
462 // Tests that the field is classified as |ADDRESS_HOME_COUNTRY| when the field
463 // name contains 'region'.
TEST_F(AddressFieldTest,ParseCountryNameRegion)464 TEST_F(AddressFieldTest, ParseCountryNameRegion) {
465   FormFieldData field;
466   field.form_control_type = "text";
467 
468   field.label = ASCIIToUTF16("Land");
469   field.name = ASCIIToUTF16("client_region");
470   list_.push_back(
471       std::make_unique<AutofillField>(field, ASCIIToUTF16("country1")));
472 
473   AutofillScanner scanner(list_);
474   field_ = Parse(&scanner);
475   ASSERT_NE(nullptr, field_.get());
476   field_->AddClassificationsForTesting(&field_candidates_map_);
477 
478   ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("country1")) !=
479               field_candidates_map_.end());
480   EXPECT_EQ(
481       ADDRESS_HOME_COUNTRY,
482       field_candidates_map_[ASCIIToUTF16("country1")].BestHeuristicType());
483 }
484 
485 }  // namespace autofill
486