| 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 "components/autofill/core/browser/credit_card_field.h" | 5 #include "components/autofill/core/browser/credit_card_field.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/macros.h" | 10 #include "base/macros.h" |
| 11 #include "base/memory/ptr_util.h" | 11 #include "base/memory/ptr_util.h" |
| 12 #include "base/strings/utf_string_conversions.h" | 12 #include "base/strings/utf_string_conversions.h" |
| 13 #include "components/autofill/core/browser/autofill_field.h" | 13 #include "components/autofill/core/browser/autofill_field.h" |
| 14 #include "components/autofill/core/browser/autofill_scanner.h" | 14 #include "components/autofill/core/browser/autofill_scanner.h" |
| 15 #include "components/autofill/core/common/form_field_data.h" | 15 #include "components/autofill/core/common/form_field_data.h" |
| 16 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
| 17 | 17 |
| 18 using base::ASCIIToUTF16; | 18 using base::ASCIIToUTF16; |
| 19 | 19 |
| 20 namespace autofill { | 20 namespace autofill { |
| 21 | 21 |
| 22 class CreditCardFieldTest : public testing::Test { | 22 class CreditCardFieldTestBase { |
| 23 public: | 23 public: |
| 24 CreditCardFieldTest() {} | 24 CreditCardFieldTestBase() {} |
| 25 ~CreditCardFieldTest() override {} | 25 ~CreditCardFieldTestBase() {} |
| 26 | 26 |
| 27 protected: | 27 protected: |
| 28 std::vector<std::unique_ptr<AutofillField>> list_; | 28 std::vector<std::unique_ptr<AutofillField>> list_; |
| 29 std::unique_ptr<const CreditCardField> field_; | 29 std::unique_ptr<const CreditCardField> field_; |
| 30 FieldCandidatesMap field_candidates_map_; | 30 FieldCandidatesMap field_candidates_map_; |
| 31 | 31 |
| 32 // Parses the contents of |list_| as a form, and stores the result into | 32 // Parses the contents of |list_| as a form, and stores the result into |
| 33 // |field_|. | 33 // |field_|. |
| 34 void Parse() { | 34 void Parse() { |
| 35 AutofillScanner scanner(list_); | 35 AutofillScanner scanner(list_); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 52 } | 52 } |
| 53 } | 53 } |
| 54 | 54 |
| 55 // Associates fields with their corresponding types, based on the previous | 55 // Associates fields with their corresponding types, based on the previous |
| 56 // call to Parse(). | 56 // call to Parse(). |
| 57 void AddClassifications() { | 57 void AddClassifications() { |
| 58 return field_->AddClassifications(&field_candidates_map_); | 58 return field_->AddClassifications(&field_candidates_map_); |
| 59 } | 59 } |
| 60 | 60 |
| 61 private: | 61 private: |
| 62 DISALLOW_COPY_AND_ASSIGN(CreditCardFieldTestBase); |
| 63 }; |
| 64 |
| 65 class CreditCardFieldTest : public CreditCardFieldTestBase, |
| 66 public testing::Test { |
| 67 public: |
| 68 CreditCardFieldTest() {} |
| 69 |
| 70 private: |
| 62 DISALLOW_COPY_AND_ASSIGN(CreditCardFieldTest); | 71 DISALLOW_COPY_AND_ASSIGN(CreditCardFieldTest); |
| 63 }; | 72 }; |
| 64 | 73 |
| 65 TEST_F(CreditCardFieldTest, Empty) { | 74 TEST_F(CreditCardFieldTest, Empty) { |
| 66 Parse(); | 75 Parse(); |
| 67 ASSERT_EQ(nullptr, field_.get()); | 76 ASSERT_EQ(nullptr, field_.get()); |
| 68 } | 77 } |
| 69 | 78 |
| 70 TEST_F(CreditCardFieldTest, NonParse) { | 79 TEST_F(CreditCardFieldTest, NonParse) { |
| 71 list_.push_back(base::MakeUnique<AutofillField>()); | 80 list_.push_back(base::MakeUnique<AutofillField>()); |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 285 ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("month3")) != | 294 ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("month3")) != |
| 286 field_candidates_map_.end()); | 295 field_candidates_map_.end()); |
| 287 EXPECT_EQ(CREDIT_CARD_EXP_MONTH, | 296 EXPECT_EQ(CREDIT_CARD_EXP_MONTH, |
| 288 field_candidates_map_[ASCIIToUTF16("month3")].BestHeuristicType()); | 297 field_candidates_map_[ASCIIToUTF16("month3")].BestHeuristicType()); |
| 289 ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("year4")) != | 298 ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("year4")) != |
| 290 field_candidates_map_.end()); | 299 field_candidates_map_.end()); |
| 291 EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR, | 300 EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR, |
| 292 field_candidates_map_[ASCIIToUTF16("year4")].BestHeuristicType()); | 301 field_candidates_map_[ASCIIToUTF16("year4")].BestHeuristicType()); |
| 293 } | 302 } |
| 294 | 303 |
| 295 TEST_F(CreditCardFieldTest, ParseExpField) { | 304 typedef struct { |
| 296 typedef struct { | 305 const std::string label; |
| 297 const std::string label; | 306 const int max_length; |
| 298 const int max_length; | 307 const ServerFieldType expected_prediction; |
| 299 const ServerFieldType expected_prediction; | 308 } ParseExpFieldTestCase; |
| 300 } TestCase; | |
| 301 | 309 |
| 302 TestCase test_cases[] = { | 310 class ParseExpFieldTest : public CreditCardFieldTestBase, |
| 303 // General label, no maxlength. | 311 public testing::TestWithParam<ParseExpFieldTestCase> { |
| 304 {"Expiration Date", 0, CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR}, | 312 }; |
| 305 // General label, maxlength 4. | |
| 306 {"Expiration Date", 4, CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR}, | |
| 307 // General label, maxlength 5. | |
| 308 {"Expiration Date", 5, CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR}, | |
| 309 // General label, maxlength 6. | |
| 310 {"Expiration Date", 6, CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR}, | |
| 311 // General label, maxlength 7. | |
| 312 {"Expiration Date", 7, CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR}, | |
| 313 // General label, large maxlength. | |
| 314 {"Expiration Date", 12, CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR}, | |
| 315 | 313 |
| 316 // Unsupported maxlength, general label. | 314 TEST_P(ParseExpFieldTest, ParseExpField) { |
| 317 {"Expiration Date", 3, UNKNOWN_TYPE}, | 315 auto test_case = GetParam(); |
| 318 // Unsupported maxlength, two digit year label. | 316 // Clean up after previous test cases. |
| 319 {"Expiration Date (MM/YY)", 3, UNKNOWN_TYPE}, | 317 list_.clear(); |
| 320 // Unsupported maxlength, four digit year label. | 318 field_.reset(); |
| 321 {"Expiration Date (MM/YYYY)", 3, UNKNOWN_TYPE}, | 319 field_candidates_map_.clear(); |
| 322 | 320 |
| 323 // Two digit year, simple label. | 321 FormFieldData field; |
| 324 {"MM / YY", 0, CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR}, | 322 field.form_control_type = "text"; |
| 325 // Two digit year, with slash (MM/YY). | |
| 326 {"Expiration Date (MM/YY)", 0, CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR}, | |
| 327 // Two digit year, no slash (MMYY). | |
| 328 {"Expiration Date (MMYY)", 4, CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR}, | |
| 329 // Two digit year, with slash and maxlength (MM/YY). | |
| 330 {"Expiration Date (MM/YY)", 5, CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR}, | |
| 331 // Two digit year, with slash and large maxlength (MM/YY). | |
| 332 {"Expiration Date (MM/YY)", 12, CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR}, | |
| 333 | 323 |
| 334 // Four digit year, simple label. | 324 field.label = ASCIIToUTF16("Name on Card"); |
| 335 {"MM / YYYY", 0, CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR}, | 325 field.name = ASCIIToUTF16("name_on_card"); |
| 336 // Four digit year, with slash (MM/YYYY). | 326 list_.push_back( |
| 337 {"Expiration Date (MM/YYYY)", 0, CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR}, | 327 base::MakeUnique<AutofillField>(field, ASCIIToUTF16("name1"))); |
| 338 // Four digit year, no slash (MMYYYY). | |
| 339 {"Expiration Date (MMYYYY)", 6, CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR}, | |
| 340 // Four digit year, with slash and maxlength (MM/YYYY). | |
| 341 {"Expiration Date (MM/YYYY)", 7, CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR}, | |
| 342 // Four digit year, with slash and large maxlength (MM/YYYY). | |
| 343 {"Expiration Date (MM/YYYY)", 12, CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR}, | |
| 344 | 328 |
| 345 // Four digit year label with restrictive maxlength (4). | 329 field.label = ASCIIToUTF16("Card Number"); |
| 346 {"Expiration Date (MM/YYYY)", 4, CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR}, | 330 field.name = ASCIIToUTF16("card_number"); |
| 347 // Four digit year label with restrictive maxlength (5). | 331 list_.push_back(base::MakeUnique<AutofillField>(field, ASCIIToUTF16("num2"))); |
| 348 {"Expiration Date (MM/YYYY)", 5, CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR}, | |
| 349 }; | |
| 350 | 332 |
| 351 for (const TestCase &test_case : test_cases) { | 333 field.label = ASCIIToUTF16(test_case.label); |
| 352 // Clean up after previous test cases. | 334 if (test_case.max_length != 0) { |
| 353 list_.clear(); | 335 field.max_length = test_case.max_length; |
| 354 field_.reset(); | 336 } |
| 355 field_candidates_map_.clear(); | 337 field.name = ASCIIToUTF16("cc_exp"); |
| 338 list_.push_back(base::MakeUnique<AutofillField>(field, ASCIIToUTF16("exp3"))); |
| 356 | 339 |
| 357 FormFieldData field; | 340 Parse(); |
| 358 field.form_control_type = "text"; | |
| 359 | 341 |
| 360 field.label = ASCIIToUTF16("Name on Card"); | 342 // Assists in identifing which case has failed. |
| 361 field.name = ASCIIToUTF16("name_on_card"); | 343 SCOPED_TRACE(test_case.expected_prediction); |
| 362 list_.push_back( | 344 SCOPED_TRACE(test_case.max_length); |
| 363 base::MakeUnique<AutofillField>(field, ASCIIToUTF16("name1"))); | 345 SCOPED_TRACE(test_case.label); |
| 364 | 346 |
| 365 field.label = ASCIIToUTF16("Card Number"); | 347 if (test_case.expected_prediction == UNKNOWN_TYPE) { |
| 366 field.name = ASCIIToUTF16("card_number"); | 348 // Expect failure and continue to next test case. |
| 367 list_.push_back( | 349 // The expiry date is a required field for credit card forms, and thus the |
| 368 base::MakeUnique<AutofillField>(field, ASCIIToUTF16("num2"))); | 350 // parse sets |field_| to nullptr. |
| 351 EXPECT_EQ(nullptr, field_.get()); |
| 352 return; |
| 353 } |
| 369 | 354 |
| 370 field.label = ASCIIToUTF16(test_case.label); | 355 // Ensure that the form was determined as valid. |
| 371 if (test_case.max_length != 0) { | 356 ASSERT_NE(nullptr, field_.get()); |
| 372 field.max_length = test_case.max_length; | 357 AddClassifications(); |
| 373 } | 358 ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("name1")) != |
| 374 field.name = ASCIIToUTF16("cc_exp"); | 359 field_candidates_map_.end()); |
| 375 list_.push_back( | 360 EXPECT_EQ(CREDIT_CARD_NAME_FULL, |
| 376 base::MakeUnique<AutofillField>(field, ASCIIToUTF16("exp3"))); | 361 field_candidates_map_[ASCIIToUTF16("name1")].BestHeuristicType()); |
| 377 | 362 |
| 378 Parse(); | 363 ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("num2")) != |
| 364 field_candidates_map_.end()); |
| 365 EXPECT_EQ(CREDIT_CARD_NUMBER, |
| 366 field_candidates_map_[ASCIIToUTF16("num2")].BestHeuristicType()); |
| 379 | 367 |
| 380 // Assists in identifing which case has failed. | 368 ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("exp3")) != |
| 381 SCOPED_TRACE(test_case.expected_prediction); | 369 field_candidates_map_.end()); |
| 382 SCOPED_TRACE(test_case.max_length); | 370 EXPECT_EQ(test_case.expected_prediction, |
| 383 SCOPED_TRACE(test_case.label); | 371 field_candidates_map_[ASCIIToUTF16("exp3")].BestHeuristicType()); |
| 372 } |
| 384 | 373 |
| 385 if (test_case.expected_prediction == UNKNOWN_TYPE) { | 374 INSTANTIATE_TEST_CASE_P( |
| 386 // Expect failure and continue to next test case. | 375 CreditCardFieldTest, |
| 387 // The expiry date is a required field for credit card forms, and thus the | 376 ParseExpFieldTest, |
| 388 // parse sets |field_| to nullptr. | 377 testing::Values( |
| 389 EXPECT_EQ(nullptr, field_.get()); | 378 // General label, no maxlength. |
| 390 continue; | 379 ParseExpFieldTestCase{"Expiration Date", 0, |
| 391 } | 380 CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR}, |
| 381 // General label, maxlength 4. |
| 382 ParseExpFieldTestCase{"Expiration Date", 4, |
| 383 CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR}, |
| 384 // General label, maxlength 5. |
| 385 ParseExpFieldTestCase{"Expiration Date", 5, |
| 386 CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR}, |
| 387 // General label, maxlength 6. |
| 388 ParseExpFieldTestCase{"Expiration Date", 6, |
| 389 CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR}, |
| 390 // General label, maxlength 7. |
| 391 ParseExpFieldTestCase{"Expiration Date", 7, |
| 392 CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR}, |
| 393 // General label, large maxlength. |
| 394 ParseExpFieldTestCase{"Expiration Date", 12, |
| 395 CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR}, |
| 392 | 396 |
| 393 // Ensure that the form was determined as valid. | 397 // Unsupported maxlength, general label. |
| 394 ASSERT_NE(nullptr, field_.get()); | 398 ParseExpFieldTestCase{"Expiration Date", 3, UNKNOWN_TYPE}, |
| 395 AddClassifications(); | 399 // Unsupported maxlength, two digit year label. |
| 396 ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("name1")) != | 400 ParseExpFieldTestCase{"Expiration Date (MM/YY)", 3, UNKNOWN_TYPE}, |
| 397 field_candidates_map_.end()); | 401 // Unsupported maxlength, four digit year label. |
| 398 EXPECT_EQ(CREDIT_CARD_NAME_FULL, | 402 ParseExpFieldTestCase{"Expiration Date (MM/YYYY)", 3, UNKNOWN_TYPE}, |
| 399 field_candidates_map_[ASCIIToUTF16("name1")].BestHeuristicType()); | |
| 400 | 403 |
| 401 ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("num2")) != | 404 // Two digit year, simple label. |
| 402 field_candidates_map_.end()); | 405 ParseExpFieldTestCase{"MM / YY", 0, CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR}, |
| 403 EXPECT_EQ(CREDIT_CARD_NUMBER, | 406 // Two digit year, with slash (MM/YY). |
| 404 field_candidates_map_[ASCIIToUTF16("num2")].BestHeuristicType()); | 407 ParseExpFieldTestCase{"Expiration Date (MM/YY)", 0, |
| 408 CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR}, |
| 409 // Two digit year, no slash (MMYY). |
| 410 ParseExpFieldTestCase{"Expiration Date (MMYY)", 4, |
| 411 CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR}, |
| 412 // Two digit year, with slash and maxlength (MM/YY). |
| 413 ParseExpFieldTestCase{"Expiration Date (MM/YY)", 5, |
| 414 CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR}, |
| 415 // Two digit year, with slash and large maxlength (MM/YY). |
| 416 ParseExpFieldTestCase{"Expiration Date (MM/YY)", 12, |
| 417 CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR}, |
| 405 | 418 |
| 406 ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("exp3")) != | 419 // Four digit year, simple label. |
| 407 field_candidates_map_.end()); | 420 ParseExpFieldTestCase{"MM / YYYY", 0, |
| 408 EXPECT_EQ(test_case.expected_prediction, | 421 CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR}, |
| 409 field_candidates_map_[ASCIIToUTF16("exp3")].BestHeuristicType()); | 422 // Four digit year, with slash (MM/YYYY). |
| 410 } | 423 ParseExpFieldTestCase{"Expiration Date (MM/YYYY)", 0, |
| 411 } | 424 CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR}, |
| 425 // Four digit year, no slash (MMYYYY). |
| 426 ParseExpFieldTestCase{"Expiration Date (MMYYYY)", 6, |
| 427 CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR}, |
| 428 // Four digit year, with slash and maxlength (MM/YYYY). |
| 429 ParseExpFieldTestCase{"Expiration Date (MM/YYYY)", 7, |
| 430 CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR}, |
| 431 // Four digit year, with slash and large maxlength (MM/YYYY). |
| 432 ParseExpFieldTestCase{"Expiration Date (MM/YYYY)", 12, |
| 433 CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR}, |
| 434 |
| 435 // Four digit year label with restrictive maxlength (4). |
| 436 ParseExpFieldTestCase{"Expiration Date (MM/YYYY)", 4, |
| 437 CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR}, |
| 438 // Four digit year label with restrictive maxlength (5). |
| 439 ParseExpFieldTestCase{"Expiration Date (MM/YYYY)", 5, |
| 440 CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR})); |
| 412 | 441 |
| 413 TEST_F(CreditCardFieldTest, ParseCreditCardHolderNameWithCCFullName) { | 442 TEST_F(CreditCardFieldTest, ParseCreditCardHolderNameWithCCFullName) { |
| 414 FormFieldData field; | 443 FormFieldData field; |
| 415 field.form_control_type = "text"; | 444 field.form_control_type = "text"; |
| 416 | 445 |
| 417 field.label = ASCIIToUTF16("Name"); | 446 field.label = ASCIIToUTF16("Name"); |
| 418 field.name = ASCIIToUTF16("ccfullname"); | 447 field.name = ASCIIToUTF16("ccfullname"); |
| 419 list_.push_back( | 448 list_.push_back( |
| 420 base::MakeUnique<AutofillField>(field, ASCIIToUTF16("name1"))); | 449 base::MakeUnique<AutofillField>(field, ASCIIToUTF16("name1"))); |
| 421 | 450 |
| (...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 798 field_candidates_map_.end()); | 827 field_candidates_map_.end()); |
| 799 EXPECT_EQ(CREDIT_CARD_VERIFICATION_CODE, | 828 EXPECT_EQ(CREDIT_CARD_VERIFICATION_CODE, |
| 800 field_candidates_map_[ASCIIToUTF16("cvc")].BestHeuristicType()); | 829 field_candidates_map_[ASCIIToUTF16("cvc")].BestHeuristicType()); |
| 801 ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("unknown")) == | 830 ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("unknown")) == |
| 802 field_candidates_map_.end()); | 831 field_candidates_map_.end()); |
| 803 ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("cvc2")) == | 832 ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("cvc2")) == |
| 804 field_candidates_map_.end()); | 833 field_candidates_map_.end()); |
| 805 } | 834 } |
| 806 | 835 |
| 807 } // namespace autofill | 836 } // namespace autofill |
| OLD | NEW |