Commit a332fd8b authored by David Jean's avatar David Jean Committed by Commit Bot

[ios] Add pure obj-c credit card for manual fallback

Includes translator from autofill::CreditCard. Will be used in manual_fill in a follow up cl.

Bug: 845472
Change-Id: I1f70757e5de4ace6f12a3dfebbcf263c960a7d57
Reviewed-on: https://chromium-review.googlesource.com/c/1331391Reviewed-by: default avatarJavier Ernesto Flores Robles <javierrobles@chromium.org>
Commit-Queue: David Jean <djean@chromium.org>
Cr-Commit-Position: refs/heads/master@{#607583}
parent 747e3e8b
......@@ -16,6 +16,8 @@ source_set("manual_fill") {
"card_mediator.mm",
"credential_password_form.h",
"credential_password_form.mm",
"credit_card_form.h",
"credit_card_form.mm",
"fallback_coordinator.h",
"fallback_coordinator.mm",
"form_observer_helper.h",
......@@ -37,6 +39,7 @@ source_set("manual_fill") {
"//components/keyed_service/core:core",
"//components/password_manager/core/browser",
"//ios/chrome/app/strings:ios_strings_grit",
"//ios/chrome/browser",
"//ios/chrome/browser/autofill",
"//ios/chrome/browser/autofill:autofill_shared",
"//ios/chrome/browser/autofill/manual_fill:manual_fill",
......@@ -69,6 +72,8 @@ source_set("manual_fill_ui") {
"card_view_controller.mm",
"credential.h",
"credential.mm",
"credit_card.h",
"credit_card.mm",
"fallback_view_controller.h",
"fallback_view_controller.mm",
"keyboard_observer_helper.h",
......@@ -124,18 +129,21 @@ source_set("unit_tests") {
sources = [
"credential_password_form_unittest.mm",
"credential_unittest.mm",
"credit_card_form_unittest.mm",
"credit_card_unittest.mm",
"form_observer_helper_unittest.mm",
]
deps = [
":manual_fill",
":manual_fill_ui",
"//base:base",
"//components/autofill/core/common:common",
"//base",
"//components/autofill/core/browser",
"//components/autofill/core/common",
"//components/autofill/ios/form_util:form_util",
"//components/autofill/ios/form_util:test_support",
"//ios/chrome/browser/web_state_list",
"//ios/chrome/browser/web_state_list:test_support",
"//ios/chrome/browser/web_state_list:web_state_list",
"//ios/web/public/test/fakes:fakes",
"//ios/web/public/test/fakes",
"//testing/gtest:gtest",
"//third_party/ocmock:ocmock",
"//url:url",
......@@ -153,7 +161,7 @@ source_set("requesters") {
"//base",
"//components/autofill/core/browser",
"//components/autofill/core/common",
"//components/autofill/ios/browser:browser",
"//components/autofill/ios/browser",
"//ios/chrome/browser/ui/payments:requesters",
"//ios/chrome/browser/web_state_list:web_state_list",
"//ios/web/public:public",
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef IOS_CHROME_BROWSER_UI_AUTOFILL_MANUAL_FILL_CREDIT_CARD_H_
#define IOS_CHROME_BROWSER_UI_AUTOFILL_MANUAL_FILL_CREDIT_CARD_H_
#import <Foundation/Foundation.h>
// This represents a credit card to use with manual fill.
@interface ManualFillCreditCard : NSObject
// The credit card GUID, for match with c++ version.
@property(nonatomic, readonly) NSString* GUID;
// The provider network related to this credit card.
@property(nonatomic, readonly) NSString* network;
// The bank related to this credit card. Can be nil.
@property(nonatomic, readonly) NSString* bankName;
// The credit card holder name.
@property(nonatomic, readonly) NSString* cardHolder;
// The credit card number. Can be nil if the card is masked and requires
// unlocking though CVC input.
@property(nonatomic, readonly) NSString* number;
// The credit card number obfuscated for display purpose.
@property(nonatomic, readonly) NSString* obfuscatedNumber;
// The credit card expiration year.
@property(nonatomic, readonly) NSString* expirationYear;
// The credit card expiration month.
@property(nonatomic, readonly) NSString* expirationMonth;
// Default init. |GUID| and |number| are the only fields considered for
// equality, so we can differentiate between an obfuscated and a comlete one.
- (instancetype)initWithGUID:(NSString*)GUID
network:(NSString*)network
bankName:(NSString*)bankName
cardHolder:(NSString*)cardHolder
number:(NSString*)number
obfuscatedNumber:(NSString*)obfuscatedNumber
expirationYear:(NSString*)expirationYear
expirationMonth:(NSString*)expirationMonth
NS_DESIGNATED_INITIALIZER;
// Unavailable. Please use |initWithGuid:network:bankName:cardholder:number:
// obfuscatedNumber:expirationYear:expirationMonth:|.
- (instancetype)init NS_UNAVAILABLE;
@end
#endif // IOS_CHROME_BROWSER_UI_AUTOFILL_MANUAL_FILL_CREDIT_CARD_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/ui/autofill/manual_fill/credit_card.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
@implementation ManualFillCreditCard
- (instancetype)initWithGUID:(NSString*)GUID
network:(NSString*)network
bankName:(NSString*)bankName
cardHolder:(NSString*)cardHolder
number:(NSString*)number
obfuscatedNumber:(NSString*)obfuscatedNumber
expirationYear:(NSString*)expirationYear
expirationMonth:(NSString*)expirationMonth {
self = [super init];
if (self) {
_GUID = [GUID copy];
_network = [network copy];
_bankName = [bankName copy];
_cardHolder = [cardHolder copy];
_number = [number copy];
_obfuscatedNumber = [obfuscatedNumber copy];
_expirationYear = [expirationYear copy];
_expirationMonth = [expirationMonth copy];
}
return self;
}
- (BOOL)isEqual:(id)object {
if (!object) {
return NO;
}
if (self == object) {
return YES;
}
if (![object isMemberOfClass:[ManualFillCreditCard class]]) {
return NO;
}
ManualFillCreditCard* otherObject = (ManualFillCreditCard*)object;
// Guid and number matches or not, there's no need to care about the other
// fields. 'Number' differenciate between the same card obfuscated or not.
if (![otherObject.GUID isEqual:self.GUID]) {
return NO;
}
if (![otherObject.number isEqual:self.number]) {
return NO;
}
return YES;
}
- (NSUInteger)hash {
return [self.GUID hash] ^ [self.number hash];
}
- (NSString*)description {
// Not returning raw number, just obfuscated number, in case this ends up in
// logs.
return [NSString
stringWithFormat:
@"<%@ (%p): GUID: %@, network: %@, bankName: %@, cardHolder: %@, "
@"obfuscatedNumber: %@, expirationYear: %@, expirationMonth: %@>",
NSStringFromClass([self class]), self, self.GUID, self.network,
self.bankName, self.cardHolder, self.obfuscatedNumber,
self.expirationYear, self.expirationMonth];
}
@end
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef IOS_CHROME_BROWSER_UI_AUTOFILL_MANUAL_FILL_CREDIT_CARD_FORM_H_
#define IOS_CHROME_BROWSER_UI_AUTOFILL_MANUAL_FILL_CREDIT_CARD_FORM_H_
#import "ios/chrome/browser/ui/autofill/manual_fill/credit_card.h"
namespace autofill {
class CreditCard;
}
@interface ManualFillCreditCard (CreditCard)
// Convenience initializer from a autofill::CreditCard. It also prepares some
// fields for user presentation, like creating an obfuscated version of the
// credit card number and formatting month/year fields.
- (instancetype)initWithCreditCard:(const autofill::CreditCard&)creditCard;
@end
#endif // IOS_CHROME_BROWSER_UI_AUTOFILL_MANUAL_FILL_CREDIT_CARD_FORM_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/ui/autofill/manual_fill/credit_card_form.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/browser/credit_card.h"
#import "components/autofill/ios/browser/credit_card_util.h"
#include "ios/chrome/browser/application_context.h"
#include "url/gurl.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
@implementation ManualFillCreditCard (CreditCardForm)
- (instancetype)initWithCreditCard:(const autofill::CreditCard&)creditCard {
NSString* GUID =
base::SysUTF16ToNSString(base::ASCIIToUTF16(creditCard.guid()));
NSString* network = base::SysUTF16ToNSString(creditCard.NetworkForDisplay());
NSString* bankName =
base::SysUTF16ToNSString(base::ASCIIToUTF16(creditCard.bank_name()));
NSString* cardHolder = autofill::GetCreditCardName(
creditCard, GetApplicationContext()->GetApplicationLocale());
NSString* number =
base::SysUTF16ToNSString(autofill::CreditCard::StripSeparators(
creditCard.GetRawInfo(autofill::CREDIT_CARD_NUMBER)));
// Unicode characters used in card number:
// - 0x0020 - Space.
// - 0x2060 - WORD-JOINER (makes string undivisible).
constexpr base::char16 separator[] = {0x2060, 0x0020, 0};
const base::string16 digits = creditCard.LastFourDigits();
NSString* obfuscatedNumber = base::SysUTF16ToNSString(
autofill::kMidlineEllipsis + base::string16(separator) +
autofill::kMidlineEllipsis + base::string16(separator) +
autofill::kMidlineEllipsis + base::string16(separator) + digits);
// Use 2 digits year.
NSString* expirationYear =
[NSString stringWithFormat:@"%02d", creditCard.expiration_year() % 100];
NSString* expirationMonth =
[NSString stringWithFormat:@"%02d", creditCard.expiration_month()];
return [self initWithGUID:GUID
network:network
bankName:bankName
cardHolder:cardHolder
number:number
obfuscatedNumber:obfuscatedNumber
expirationYear:expirationYear
expirationMonth:expirationMonth];
}
@end
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/ui/autofill/manual_fill/credit_card_form.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/browser/credit_card.h"
#include "testing/platform_test.h"
#include "url/gurl.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
using autofill::CreditCard;
using ManualFillCreditCardFormAutofilliOSTest = PlatformTest;
// Tests the creation of a unobfuscated credit card from an
// autofill::CreditCard.
TEST_F(ManualFillCreditCardFormAutofilliOSTest, CreationUnobfuscated) {
NSString* GUID = @"1234-5678-abcd";
NSString* bankName = @"Bank of 'Merica";
NSString* cardHolder = @"Fred Itcard";
// Visa -> starts with 4.
NSString* number = @"4321 4321 4321 1234";
NSString* expirationYear = @"19";
NSString* expirationMonth = @"1";
CreditCard autofillCreditCard = CreditCard();
autofillCreditCard.set_guid(
base::UTF16ToASCII(base::SysNSStringToUTF16(GUID)));
autofillCreditCard.SetNumber(base::SysNSStringToUTF16(number));
autofillCreditCard.set_bank_name(base::SysNSStringToUTF8(bankName));
autofillCreditCard.SetRawInfo(autofill::CREDIT_CARD_NAME_FULL,
base::SysNSStringToUTF16(cardHolder));
autofillCreditCard.SetRawInfo(autofill::CREDIT_CARD_EXP_MONTH,
base::SysNSStringToUTF16(expirationMonth));
autofillCreditCard.SetRawInfo(autofill::CREDIT_CARD_EXP_2_DIGIT_YEAR,
base::SysNSStringToUTF16(expirationYear));
ManualFillCreditCard* manualFillCard =
[[ManualFillCreditCard alloc] initWithCreditCard:autofillCreditCard];
EXPECT_TRUE(manualFillCard);
EXPECT_TRUE([GUID isEqualToString:manualFillCard.GUID]);
EXPECT_TRUE([@"Visa" isEqualToString:manualFillCard.network]);
EXPECT_TRUE([bankName isEqualToString:manualFillCard.bankName]);
EXPECT_TRUE([@"4321432143211234" isEqualToString:manualFillCard.number]);
EXPECT_TRUE([manualFillCard.obfuscatedNumber containsString:@"1234"]);
EXPECT_FALSE([manualFillCard.obfuscatedNumber containsString:@"4321"]);
EXPECT_TRUE([cardHolder isEqualToString:manualFillCard.cardHolder]);
// Test month and padding of months.
EXPECT_TRUE([@"01" isEqualToString:manualFillCard.expirationMonth]);
EXPECT_TRUE([expirationYear isEqualToString:manualFillCard.expirationYear]);
}
// Tests the creation of an obfuscated credit card from an
// autofill::CreditCard.
TEST_F(ManualFillCreditCardFormAutofilliOSTest, CreationObfuscated) {
NSString* GUID = @"1234-5678-abcd";
NSString* bankName = @"Bank of 'Merica";
NSString* cardHolder = @"Fred Itcard";
NSString* number = @"1234";
NSString* expirationYear = @"19";
NSString* expirationMonth = @"1";
CreditCard autofillCreditCard = CreditCard();
autofillCreditCard.set_record_type(autofill::CreditCard::MASKED_SERVER_CARD);
autofillCreditCard.set_guid(
base::UTF16ToASCII(base::SysNSStringToUTF16(GUID)));
autofillCreditCard.SetNumber(base::SysNSStringToUTF16(number));
autofillCreditCard.SetNetworkForMaskedCard(autofill::kVisaCard);
autofillCreditCard.set_bank_name(base::SysNSStringToUTF8(bankName));
autofillCreditCard.SetRawInfo(autofill::CREDIT_CARD_NAME_FULL,
base::SysNSStringToUTF16(cardHolder));
autofillCreditCard.SetRawInfo(autofill::CREDIT_CARD_EXP_MONTH,
base::SysNSStringToUTF16(expirationMonth));
autofillCreditCard.SetRawInfo(autofill::CREDIT_CARD_EXP_2_DIGIT_YEAR,
base::SysNSStringToUTF16(expirationYear));
ManualFillCreditCard* manualFillCard =
[[ManualFillCreditCard alloc] initWithCreditCard:autofillCreditCard];
EXPECT_TRUE(manualFillCard);
EXPECT_TRUE([GUID isEqualToString:manualFillCard.GUID]);
EXPECT_TRUE([@"Visa" isEqualToString:manualFillCard.network]);
EXPECT_TRUE([bankName isEqualToString:manualFillCard.bankName]);
EXPECT_TRUE([number isEqualToString:manualFillCard.number]);
EXPECT_TRUE([manualFillCard.obfuscatedNumber containsString:@"1234"]);
EXPECT_FALSE([manualFillCard.obfuscatedNumber containsString:@"4321"]);
EXPECT_TRUE([cardHolder isEqualToString:manualFillCard.cardHolder]);
// Test month and padding of months.
EXPECT_TRUE([@"01" isEqualToString:manualFillCard.expirationMonth]);
EXPECT_TRUE([expirationYear isEqualToString:manualFillCard.expirationYear]);
}
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/ui/autofill/manual_fill/credit_card.h"
#include "testing/platform_test.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
using ManualFillCreditCardiOSTest = PlatformTest;
// Tests that a credential is correctly created.
TEST_F(ManualFillCreditCardiOSTest, Creation) {
NSString* GUID = @"1234-5678-abcd";
NSString* network = @"Viza";
NSString* bankName = @"Bank of 'Merica";
NSString* cardHolder = @"Fred Itcard";
NSString* number = @"4321 1234 4321 1234";
NSString* obfuscatedNumber = @"**** **** **** 1234";
NSString* expirationYear = @"19";
NSString* expirationMonth = @"10";
ManualFillCreditCard* card =
[[ManualFillCreditCard alloc] initWithGUID:GUID
network:network
bankName:bankName
cardHolder:cardHolder
number:number
obfuscatedNumber:obfuscatedNumber
expirationYear:expirationYear
expirationMonth:expirationMonth];
EXPECT_TRUE(card);
EXPECT_TRUE([GUID isEqualToString:card.GUID]);
EXPECT_TRUE([network isEqualToString:card.network]);
EXPECT_TRUE([cardHolder isEqualToString:card.cardHolder]);
EXPECT_TRUE([number isEqualToString:card.number]);
EXPECT_TRUE([obfuscatedNumber isEqualToString:card.obfuscatedNumber]);
EXPECT_TRUE([expirationYear isEqualToString:card.expirationYear]);
EXPECT_TRUE([expirationMonth isEqualToString:card.expirationMonth]);
}
// Test equality between credit cards.
TEST_F(ManualFillCreditCardiOSTest, Equality) {
NSString* GUID = @"1234-5678-abcd";
NSString* network = @"Viza";
NSString* bankName = @"Bank of 'Merica";
NSString* cardHolder = @"Fred Itcard";
NSString* number = @"4321 1234 4321 1234";
NSString* obfuscatedNumber = @"**** **** **** 1234";
NSString* expirationYear = @"19";
NSString* expirationMonth = @"10";
ManualFillCreditCard* card =
[[ManualFillCreditCard alloc] initWithGUID:GUID
network:network
bankName:bankName
cardHolder:cardHolder
number:number
obfuscatedNumber:obfuscatedNumber
expirationYear:expirationYear
expirationMonth:expirationMonth];
ManualFillCreditCard* equalCard =
[[ManualFillCreditCard alloc] initWithGUID:GUID
network:network
bankName:bankName
cardHolder:cardHolder
number:number
obfuscatedNumber:obfuscatedNumber
expirationYear:expirationYear
expirationMonth:expirationMonth];
EXPECT_TRUE([card isEqual:equalCard]);
ManualFillCreditCard* differentGuidCredential =
[[ManualFillCreditCard alloc] initWithGUID:@"wxyz-8765-4321"
network:network
bankName:bankName
cardHolder:cardHolder
number:number
obfuscatedNumber:obfuscatedNumber
expirationYear:expirationYear
expirationMonth:expirationMonth];
EXPECT_FALSE([card isEqual:differentGuidCredential]);
// Guid is the main differentiator, and as long as the guids are equal,
// the other fields do not mather.
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment