Skip to content

Commit

Permalink
Collect Device Data (#339)
Browse files Browse the repository at this point in the history
* Add deviceData property to BTDropInResult; populate it with PPDataCollector deviceData
* Add tests for deviceData collection in BTDropInResult
  • Loading branch information
scannillo authored Jul 20, 2021
1 parent d703404 commit 8511233
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 0 deletions.
4 changes: 4 additions & 0 deletions BraintreeDropIn.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
42EA70662616682800B7E626 /* BTDropInResult_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 42EA70652616682800B7E626 /* BTDropInResult_Internal.h */; };
8005E86125BB32A6003EC2AC /* MockVenmoDriver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8005E86025BB32A6003EC2AC /* MockVenmoDriver.swift */; };
8005E86625BB34B5003EC2AC /* MockAPIClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8005E86525BB34B5003EC2AC /* MockAPIClient.swift */; };
8038FA13269789ED007BE751 /* MockPPDataCollector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8038FA12269789ED007BE751 /* MockPPDataCollector.swift */; };
8053850226162ED80085B16C /* BTConfiguration+DropIn.h in Headers */ = {isa = PBXBuildFile; fileRef = 8053850126162ED80085B16C /* BTConfiguration+DropIn.h */; settings = {ATTRIBUTES = (Private, ); }; };
80538508261630430085B16C /* BTConfiguration+DropIn.m in Sources */ = {isa = PBXBuildFile; fileRef = 80538507261630430085B16C /* BTConfiguration+DropIn.m */; };
805952552615247900DAB6C3 /* BTDropInLocalization_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 805952542615247900DAB6C3 /* BTDropInLocalization_Internal.h */; settings = {ATTRIBUTES = (Private, ); }; };
Expand Down Expand Up @@ -244,6 +245,7 @@
8005E86525BB34B5003EC2AC /* MockAPIClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockAPIClient.swift; sourceTree = "<group>"; };
800FC5E125802B5600DEE132 /* BTUIKMasterCardVectorArtView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BTUIKMasterCardVectorArtView.m; sourceTree = "<group>"; };
800FC5E225802B5600DEE132 /* BTUIKMasterCardVectorArtView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BTUIKMasterCardVectorArtView.h; sourceTree = "<group>"; };
8038FA12269789ED007BE751 /* MockPPDataCollector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockPPDataCollector.swift; sourceTree = "<group>"; };
8053850126162ED80085B16C /* BTConfiguration+DropIn.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "BTConfiguration+DropIn.h"; sourceTree = "<group>"; };
80538507261630430085B16C /* BTConfiguration+DropIn.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "BTConfiguration+DropIn.m"; sourceTree = "<group>"; };
805952542615247900DAB6C3 /* BTDropInLocalization_Internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BTDropInLocalization_Internal.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -621,6 +623,7 @@
8005E86025BB32A6003EC2AC /* MockVenmoDriver.swift */,
4237D7FD25E5BF8D006F6CE3 /* UIFont+BTUIKTests.swift */,
42A10AD8230EE4D600892302 /* UnitTests-Bridging-Header.h */,
8038FA12269789ED007BE751 /* MockPPDataCollector.swift */,
);
path = UnitTests;
sourceTree = "<group>";
Expand Down Expand Up @@ -961,6 +964,7 @@
A50ED7A61D8AF8C400A78EF0 /* BTPaymentSelectionViewControllerTests.m in Sources */,
425B83982347D3990015D1A4 /* BTUIKAppearanceTests.swift in Sources */,
4245DAF3256C721D00F1A413 /* FakeApplication.swift in Sources */,
8038FA13269789ED007BE751 /* MockPPDataCollector.swift in Sources */,
0358590B203E09E200FCE1B7 /* BTDropInRequestTests.m in Sources */,
4225EA87257EC59600923CE3 /* BTPaymentMethodNonce+DropInTests.swift in Sources */,
);
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Braintree iOS Drop-in SDK - Release Notes

## unreleased
* Add `deviceData` to `BTDropInResult`

## 9.1.0 (2021-07-01)
* Increase valid Discover card length to 19 digits
* iOS 15 Support
Expand Down
39 changes: 39 additions & 0 deletions Sources/BraintreeDropIn/Models/BTDropInResult.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,43 @@
#import <BraintreeCore/BraintreeCore.h>
#endif

// Import PayPalDataCollector (Swift) module
#if __has_include(<Braintree/Braintree-Swift.h>) // CocoaPods
#import <Braintree/Braintree-Swift.h>

#elif SWIFT_PACKAGE // SPM
/* Use @import for SPM support
* See https://forums.swift.org/t/using-a-swift-package-in-a-mixed-swift-and-objective-c-project/27348
*/
@import PayPalDataCollector;

#elif __has_include("Braintree-Swift.h") // CocoaPods for ReactNative
/* Use quoted style when importing Swift headers for ReactNative support
* See https://github.com/braintree/braintree_ios/issues/671
*/
#import "Braintree-Swift.h"

#else // Carthage
#import <PayPalDataCollector/PayPalDataCollector-Swift.h>
#endif

NSString *const BTDropInResultErrorDomain = @"com.braintreepayments.BTDropInResultErrorDomain";

@implementation BTDropInResult

// For testing
static Class PayPalDataCollectorClass;
static NSString *PayPalDataCollectorClassString = @"PPDataCollector";

- (instancetype)init {
self = [super init];
if (self) {
_deviceData = [PayPalDataCollectorClass collectPayPalDeviceData];
}

return self;
}

#pragma mark - Prefetch BTDropInResult

static NSUserDefaults *_userDefaults = nil;
Expand Down Expand Up @@ -89,4 +122,10 @@ - (NSString *)paymentDescription {
}
}

#pragma mark - Test Helpers

+ (void)setPayPalDataCollectorClass:(Class)payPalDataCollectorClass {
PayPalDataCollectorClass = payPalDataCollectorClass;
}

@end
4 changes: 4 additions & 0 deletions Sources/BraintreeDropIn/Models/BTDropInResult_Internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ NS_ASSUME_NONNULL_BEGIN
+ (void)mostRecentPaymentMethodForAPIClient:(BTAPIClient * _Nullable)apiClient
completion:(void (^)(BTDropInResult * _Nullable result, NSError * _Nullable error))completion;

// Exposed for testing
// The `PPDataCollector` class, exposed internally for injecting test doubles for unit tests
+ (void)setPayPalDataCollectorClass:(nonnull Class)payPalDataCollectorClass;

@end

NS_ASSUME_NONNULL_END
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ typedef NS_ENUM(NSInteger, BTDropInErrorType) {
/// The payment method nonce
@property (nonatomic, strong, nullable) BTPaymentMethodNonce *paymentMethod;

/**
* A `deviceData` string that represents data about a customer's device. This is generated from Braintree's advanced fraud protection service.
*
* `deviceData` should be passed into server-side calls, such as `Transaction.sale`. This enables you to collect data about a customer's device and correlate it with a session identifier on your server.
*
* Collecting and passing this data with transactions helps reduce decline rates and detect fraudulent transactions.
*/
@property (nonatomic, strong, nullable) NSString *deviceData;

/**
* Fetch a `BTDropInResult` with the customer's most recently vaulted payment method.
* If the last payment method selected from Drop-in was Apple Pay, a `BTDropInResult` with
Expand Down
9 changes: 9 additions & 0 deletions UnitTests/BTDropInResultTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,13 @@ class BTDropInResultTests: XCTestCase {

waitForExpectations(timeout: 1.0)
}

func testInit_callsPayPalDataCollectorCollectDeviceData_andSetsDeviceData() {
BTDropInResult.setPayPalDataCollectorClass(MockPPDataCollector.self)

let dropInResult = BTDropInResult()

XCTAssertTrue(MockPPDataCollector.didCollectDeviceData)
XCTAssertEqual(dropInResult.deviceData, "{\"correlation_id\":\"fake-client-metadata\"}")
}
}
12 changes: 12 additions & 0 deletions UnitTests/MockPPDataCollector.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import Foundation
@testable import PayPalDataCollector

class MockPPDataCollector: PPDataCollector {

public static var didCollectDeviceData = false

override class func collectPayPalDeviceData() -> String {
didCollectDeviceData = true
return "{\"correlation_id\":\"fake-client-metadata\"}"
}
}

0 comments on commit 8511233

Please sign in to comment.